/**
 * @file func_dynamic_menu.c
 * @author taylor peng
 * @brief
 * @version 0.1
 * @date 2021-12-24
 *
 * @copyright Copyright (c) 2021
 *
 */

#include "func_menu.h"
#include "func_mem.h"
#include "voice.h"
#include "calendar.h"
#include "touch.h"
#include "Display.h"
#include "card.h"
#include "Back_Led.h"
#include "finger.h"
#include "device.h"
#include "system.h"
#include "button.h"
#include "func_app.h"
#include "func_factory.h"
#include "control.h"
#include "Protocol.h"
#include "hal_com.h"
#include "btn_hal.h"
#ifdef FUNC_SUPPORT_FACE
#include "face.h"
#include "face_message_l.h"
#endif
#define MENU_DEBUG_EN
#ifdef MENU_DEBUG_EN
#define FUNC_MENU_LOG(format, ...) TASK_LOG(format, ##__VA_ARGS__)
#else
#define FUNC_MENU_LOG(format, ...)
#endif

typedef enum
{
    MENU_FIRST_SELECT = 0,
    MENU_ADD_ADMIN,
    MENU_CHANGE_ADMIN_PASSWORD,
    MENU_SET_ADMIN_FINGER,
    MENU_SET_ADMIN_FACE,
    MENU_ADD_NORMAL,
    MENU_DELETE_ADMIN,
    MENU_DELETE_COMMON,
    MENU_DELETE_SINGLE,
    MENU_DELETE_USERS,
    MENU_SYS_SET,
    MENU_INSTALL_PARAM_SET,
    MENU_NET_CONFIG,
    MENU_ADD_FACE,
    MENU_ADD_FP_CARD_PWD,
    MENU_ADD_CARD_PWD,
    MENU_ADD_PWD,
    MENU_ADD_FP,
    MENU_ADD_FP_PWD,
    MENU_DELETE_PWD,
    MENU_DELETE_FP,
    MENU_DELETE_FP_PWD,
    MENU_DELETE_FACE,
    MENU_DELETE_FP_CARD_PWD,
    MENU_DELETE_CARD_PWD,
    MENU_DELETE_ALLPW,
    MENU_DELETE_ALLFP,
    MENU_DELETE_ALLCARD,
    MENU_DELETE_ALLFACE,
    MENU_SYS_IDENTIFY_MODE,
    MENU_SYS_FACTORY_RESET,
    MENU_SYS_VOICE_SET,
    MENU_SYS_ALARM_SET,
    MENU_SYS_TIME_SET,
    MENU_SYS_VIEW_RECORD,
    MENU_SYS_LANGUE_SET,
    MENU_MOTOR_DIR_SET,
    MENU_MOTOR_DIRVE_LEVEL,
    MENU_MOTOR_BACK_TIME,
    MENU_AUTO_COLSE_TIME_SET,
    MENU_BACK_DRIVE_TIME_SET,
    MENU_FACE_SENSITIVITY_SET,
    MENU_JOIN_NET,
    MENU_EXIT_NET,
    MENU_SYS_ADMIN_CHANGE,
    MENU_NONE = 0XFF,
} MENU_TYPE;

typedef struct
{
    uint8_t opera_type;
    uint8_t authority;
    uint8_t pw_start;
    uint8_t pw_end;
    uint8_t fp_start;
    uint8_t fp_end;
    uint8_t card_start;
    uint8_t card_end;
#ifdef FUNC_SUPPORT_FACE
    uint8_t face_start;
    uint8_t face_end;
#endif
} USER_ID;
typedef struct
{
    uint8_t menuid;
    uint8_t Parent;                        //指向父亲的指针
    uint32_t (*pFunc)(Device_t *m_device); // 指向实际功能的函数指针，只在最后一级有用
    uint32_t (*Audio)(void);               // 刷新语音
} MENU_CONFIG_INFO;

typedef struct
{
    uint8_t times;
    uint8_t min;
    uint8_t max;
    uint8_t (*mem_get)(void);
    uint8_t (*mem_save)(uint8_t param);
} INSTALL_PARAM_INFO;

static USER_ID s_user_t;
static uint8_t s_currentmenu = 0; //菜单选项
static uint8_t s_Reflash = FALSE; //刷新标志
static uint8_t s_Cursor = 0;      //光标 带屏幕显示需要 0-N 对应实际键值 '1'-'N'
static uint32_t s_overtime = 0;   //退出菜单超时计时
static uint8_t s_menu_list = 0;

extern Device_t st_device;
extern uint8_t g_keybuff[KEY_BUFF_MAX + 1]; //共用按键缓存（节省ram）
extern uint8_t g_keylen;                    //共用按键缓存长度
static System_Timer *s_soft_reset_point = NULL;

static uint32_t Func_Menu_AddAdmin(Device_t *m_device);
static uint32_t Func_Menu_Addnormal(Device_t *m_device);
static uint32_t Func_Menu_Change_Admin_Password(Device_t *m_device);
static uint32_t Func_Menu_Set_Admin_Finger(Device_t *m_device);
static uint32_t Func_Menu_DeleteAdmin(Device_t *m_device);
static uint32_t Func_Menu_DeleteCommon(Device_t *m_device);
static uint32_t Func_Menu_Cancle_Insure_Select(Device_t *m_device);
static uint32_t Func_Menu_Identyfymode(Device_t *m_device);
static uint32_t Func_Menu_Factory_Reset(Device_t *m_device);
static uint32_t Func_Menu_VoiceSet(Device_t *m_device);
static uint32_t Func_Menu_Alarm_Set(Device_t *m_device);
static uint32_t Func_Time_Set(Device_t *m_device);
static uint32_t Func_Menu_LangueSet(Device_t *m_device);
static uint32_t Func_View_Record(Device_t *m_device);
static uint32_t Func_Menu_Motor_Set_Direction(Device_t *m_device);
static uint32_t Func_Menu_Motor_Motor_Power(Device_t *m_device);
static uint32_t Func_Menu_Motor_Back_Time(Device_t *m_device);
static uint32_t Func_Menu_Motor_Auto_Close_Time_Set(Device_t *m_device);
static uint32_t Func_Menu_Motor_Back_Drive_Time_Set(Device_t *m_device);
#ifdef WIFI_MODULE
static uint32_t Func_Menu_Net_Config(Device_t *m_device);
#endif
#ifdef FUNC_SUPPORT_FACE
static uint32_t Func_Menu_Add_Admin_Face(Device_t *m_device);
static uint32_t Func_Menu_Add_Common_Face(Device_t *m_device);
static uint32_t Func_Menu_Delete_Admin_Face(Device_t *m_device);
static uint32_t Func_Menu_Delete_Common_Face(Device_t *m_device);
static uint32_t Func_Menu_Face_Sensitivity_Set(Device_t *m_device);
#endif

static const INSTALL_PARAM_INFO s_install_param[] =
    {
        {MOTOR_PARAM_TIMES_DEFAULT, MOTOR_POWER_MIN, MOTOR_POWER_MAX, Func_Mem_Getsystem_Motor_Power, Func_Mem_Setsystem_Motor_Power},
        {MOTOR_PARAM_TIMES_DEFAULT, MOTOR_BACK_MIN, MOTOR_BACK_MAX, Func_Mem_Getsystem_Back_Time, Func_Mem_Setsystem_Back_Time},
        {MOTOR_AUTO_CLOSE_TIMES, MOTOR_AUTO_CLOSE_MIN, MOTOR_AUTO_CLOSE_MAX, Func_Mem_Getsystem_Auto_Close, Func_Mem_Setsystem_Auto_Close},
        {MOTOR_PARAM_TIMES_DEFAULT, MOTOR_BACK_DRIVER_MIN, MOTOR_BACK_DRIVER_MAX, Func_Mem_Getsystem_Back_Drive_Time, Func_Mem_Setsystem_Back_Drive_Time},
#ifdef FUNC_SUPPORT_FACE
        {FACE_SENSITIVITY_TIMES, FACE_SENSITIVITY_OFF, FACE_SENSITIVITY_HIGH, Func_Mem_Getsystem_Face_Sensitivity, Func_Mem_Setsystem_Face_Sensitivity},
#endif
};
static MENU_CONFIG_INFO g_menulist[40];
static void Func_Menu_Register(uint8_t menuid, uint8_t Parent, uint32_t (*pFunc)(Device_t *m_device), uint32_t (*Audio)(void))
{
    g_menulist[s_menu_list].menuid = menuid;
    g_menulist[s_menu_list].Parent = Parent;
    g_menulist[s_menu_list].pFunc = pFunc;
    g_menulist[s_menu_list].Audio = Audio;
    s_menu_list++;
}

static void Func_Set_User_Mode(uint8_t operate, uint8_t authority)
{
    s_user_t.opera_type = operate;
    s_user_t.authority = authority;
}
#ifdef FUNC_SUPPORT_FACE
static void Func_Set_Face_Range(uint8_t face_start, uint8_t face_end)
{
    s_user_t.face_start = face_start;
    s_user_t.face_end = face_end;
}
#endif

static void Func_Set_User_Range(uint8_t pw_start, uint8_t pw_end, uint8_t fp_start, uint8_t fp_end, uint8_t card_start, uint8_t card_end)
{
    s_user_t.pw_start = pw_start;
    s_user_t.pw_end = pw_end;
    s_user_t.fp_start = fp_start;
    s_user_t.fp_end = fp_end;
    s_user_t.card_start = card_start;
    s_user_t.card_end = card_end;
}

static void Func_Menu_Management(void)
{
    s_menu_list = 0;
    Func_Menu_Register(MENU_FIRST_SELECT, MENU_NONE, NULL, Voice_First_Select);
#ifdef FUNC_SUPPORT_FACE
#ifdef FUNC_SUPPORT_ADMINS
    if (!Device_Check(DEVICE_TYPE_FACE) && !Device_Check(DEVICE_TYPE_FP))
    {
        Func_Menu_Register(MENU_ADD_ADMIN, MENU_FIRST_SELECT, Func_Menu_AddAdmin, NULL);

        Func_Menu_Register(MENU_DELETE_ADMIN, MENU_FIRST_SELECT, Func_Menu_DeleteAdmin, NULL);

        Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, Func_Menu_Addnormal, NULL);

        Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
        Func_Menu_Register(MENU_DELETE_SINGLE, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
    }
    else
    {
        if (!Device_Check(DEVICE_TYPE_FACE)) //密码卡指纹
        {
            Func_Menu_Register(MENU_ADD_ADMIN, MENU_FIRST_SELECT, Func_Menu_AddAdmin, NULL);

            Func_Menu_Register(MENU_DELETE_ADMIN, MENU_FIRST_SELECT, Func_Menu_DeleteAdmin, NULL);

            Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, Func_Menu_Addnormal, NULL);

            Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
            Func_Menu_Register(MENU_DELETE_SINGLE, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
        }
        else if (!Device_Check(DEVICE_TYPE_FP)) //密码卡人脸
        {
            Func_Menu_Register(MENU_ADD_ADMIN, MENU_FIRST_SELECT, NULL, Voice_Add_Admin);
            Func_Menu_Register(MENU_ADD_FACE, MENU_ADD_ADMIN, Func_Menu_Add_Admin_Face, NULL);
            Func_Menu_Register(MENU_ADD_CARD_PWD, MENU_ADD_ADMIN, Func_Menu_AddAdmin, NULL);

            Func_Menu_Register(MENU_DELETE_ADMIN, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
            Func_Menu_Register(MENU_DELETE_FACE, MENU_DELETE_ADMIN, Func_Menu_Delete_Admin_Face, NULL);
            Func_Menu_Register(MENU_DELETE_CARD_PWD, MENU_DELETE_ADMIN, Func_Menu_DeleteAdmin, NULL);

            Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, NULL, Voice_Add_User);
            Func_Menu_Register(MENU_ADD_FACE, MENU_ADD_NORMAL, Func_Menu_Add_Common_Face, NULL);
            Func_Menu_Register(MENU_ADD_CARD_PWD, MENU_ADD_NORMAL, Func_Menu_Addnormal, NULL);

            Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
            Func_Menu_Register(MENU_DELETE_FACE, MENU_DELETE_COMMON, Func_Menu_Delete_Common_Face, NULL);
            Func_Menu_Register(MENU_DELETE_CARD_PWD, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
        }
        else
        {
            Func_Menu_Register(MENU_ADD_ADMIN, MENU_FIRST_SELECT, NULL, Voice_Add_Admin);
            Func_Menu_Register(MENU_ADD_FACE, MENU_ADD_ADMIN, Func_Menu_Add_Admin_Face, NULL);
            Func_Menu_Register(MENU_ADD_FP_CARD_PWD, MENU_ADD_ADMIN, Func_Menu_AddAdmin, NULL);

            Func_Menu_Register(MENU_DELETE_ADMIN, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
            Func_Menu_Register(MENU_DELETE_FACE, MENU_DELETE_ADMIN, Func_Menu_Delete_Admin_Face, NULL);
            Func_Menu_Register(MENU_DELETE_FP_CARD_PWD, MENU_DELETE_ADMIN, Func_Menu_DeleteAdmin, NULL);

            Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, NULL, Voice_Add_User);
            Func_Menu_Register(MENU_ADD_FACE, MENU_ADD_NORMAL, Func_Menu_Add_Common_Face, NULL);
            Func_Menu_Register(MENU_ADD_FP_CARD_PWD, MENU_ADD_NORMAL, Func_Menu_Addnormal, NULL);

            Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
            Func_Menu_Register(MENU_DELETE_FACE, MENU_DELETE_COMMON, Func_Menu_Delete_Common_Face, NULL);
            Func_Menu_Register(MENU_DELETE_FP_CARD_PWD, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
        }
    }
    Func_Menu_Register(MENU_DELETE_USERS, MENU_DELETE_COMMON, NULL, Voice_Second_Delete_User);
    Func_Menu_Register(MENU_SYS_SET, MENU_FIRST_SELECT, NULL, Voice_Second_SysSet);
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_INSTALL_PARAM_SET, MENU_FIRST_SELECT, NULL, Voice_Second_MotorSet);
#endif
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_NET_CONFIG, MENU_FIRST_SELECT, NULL, Voice_Second_NetSet);
#endif
    Func_Menu_Register(MENU_DELETE_ALLPW, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    if (Device_Check(DEVICE_TYPE_FP))
    {
        Func_Menu_Register(MENU_DELETE_ALLFP, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    }
    Func_Menu_Register(MENU_DELETE_ALLCARD, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    if (Device_Check(DEVICE_TYPE_FACE))
    {
        Func_Menu_Register(MENU_DELETE_ALLFACE, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    }
    Func_Menu_Register(MENU_SYS_IDENTIFY_MODE, MENU_SYS_SET, Func_Menu_Identyfymode, NULL);
    Func_Menu_Register(MENU_SYS_FACTORY_RESET, MENU_SYS_SET, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_SYS_VOICE_SET, MENU_SYS_SET, Func_Menu_VoiceSet, NULL);
    Func_Menu_Register(MENU_SYS_ALARM_SET, MENU_SYS_SET, Func_Menu_Alarm_Set, NULL);
#ifdef FUNC_SUPPORT_OLED
    Func_Menu_Register(MENU_SYS_TIME_SET, MENU_SYS_SET, Func_Time_Set, NULL);
#endif
#if defined(OPENDOOR_RECORD) || defined(ALL_KINDS_RECORD)
    Func_Menu_Register(MENU_SYS_VIEW_RECORD, MENU_SYS_SET, Func_View_Record, NULL);
#endif
#ifdef FUNC_SUPPORT_ENG
    Func_Menu_Register(MENU_SYS_LANGUE_SET, MENU_SYS_SET, Func_Menu_LangueSet, NULL);
#endif
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_MOTOR_DIR_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Set_Direction, NULL);
    Func_Menu_Register(MENU_MOTOR_DIRVE_LEVEL, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Motor_Power, NULL);
    Func_Menu_Register(MENU_MOTOR_BACK_TIME, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Time, NULL);
    Func_Menu_Register(MENU_AUTO_COLSE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Auto_Close_Time_Set, NULL);
    Func_Menu_Register(MENU_BACK_DRIVE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Drive_Time_Set, NULL);
#endif
    if (Device_Check(DEVICE_TYPE_FACE))
    {
        Func_Menu_Register(MENU_FACE_SENSITIVITY_SET, MENU_SYS_SET, Func_Menu_Face_Sensitivity_Set, NULL);
    }
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_JOIN_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
    Func_Menu_Register(MENU_EXIT_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
#endif

#else
    if (!Device_Check(DEVICE_TYPE_FACE) && !Device_Check(DEVICE_TYPE_FP))
    {
        Func_Menu_Register(MENU_CHANGE_ADMIN_PASSWORD, MENU_FIRST_SELECT, Func_Menu_Change_Admin_Password, NULL);
        Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, Func_Menu_Addnormal, NULL);
        Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, Func_Menu_DeleteCommon, NULL);
    }
    else
    {
        Func_Menu_Register(MENU_ADD_ADMIN, MENU_FIRST_SELECT, NULL, Voice_Add_Admin);
        Func_Menu_Register(MENU_CHANGE_ADMIN_PASSWORD, MENU_ADD_ADMIN, Func_Menu_Change_Admin_Password, NULL);
        if (!Device_Check(DEVICE_TYPE_FACE))
        {
            Func_Menu_Register(MENU_SET_ADMIN_FINGER, MENU_ADD_ADMIN, Func_Menu_Set_Admin_Finger, NULL);
            Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, Func_Menu_Addnormal, NULL);
            Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, Func_Menu_DeleteCommon, NULL);
        }
        else if (!Device_Check(DEVICE_TYPE_FP))
        {
            Func_Menu_Register(MENU_SET_ADMIN_FACE, MENU_ADD_ADMIN, Func_Menu_Add_Admin_Face, NULL);
            Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, NULL, Voice_Add_User);
            Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Delete_User);
        }
        else
        {
            Func_Menu_Register(MENU_SET_ADMIN_FACE, MENU_ADD_ADMIN, Func_Menu_Add_Admin_Face, NULL);
            Func_Menu_Register(MENU_SET_ADMIN_FINGER, MENU_ADD_ADMIN, Func_Menu_Set_Admin_Finger, NULL);
            Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, NULL, Voice_Add_User);
            Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Delete_User);
        }
    }
    Func_Menu_Register(MENU_DELETE_USERS, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
    Func_Menu_Register(MENU_SYS_SET, MENU_FIRST_SELECT, NULL, Voice_Second_SysSet);
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_INSTALL_PARAM_SET, MENU_FIRST_SELECT, NULL, Voice_Second_MotorSet);
#endif
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_NET_CONFIG, MENU_FIRST_SELECT, NULL, Voice_Second_NetSet);
#endif
    if (Device_Check(DEVICE_TYPE_FACE))
    {
        Func_Menu_Register(MENU_ADD_FACE, MENU_ADD_NORMAL, Func_Menu_Add_Common_Face, NULL);
        Func_Menu_Register(MENU_DELETE_FACE, MENU_DELETE_COMMON, Func_Menu_Delete_Common_Face, NULL);
        if (Device_Check(DEVICE_TYPE_FP))
        {
            Func_Menu_Register(MENU_ADD_FP_CARD_PWD, MENU_ADD_NORMAL, Func_Menu_Addnormal, NULL);
            Func_Menu_Register(MENU_DELETE_FP_CARD_PWD, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
        }
        else
        {
            Func_Menu_Register(MENU_ADD_CARD_PWD, MENU_ADD_NORMAL, Func_Menu_Addnormal, NULL);
            Func_Menu_Register(MENU_DELETE_CARD_PWD, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
        }
    }
    Func_Menu_Register(MENU_DELETE_ALLPW, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    if (Device_Check(DEVICE_TYPE_FP))
    {
        Func_Menu_Register(MENU_DELETE_ALLFP, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    }
    Func_Menu_Register(MENU_DELETE_ALLCARD, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    if (Device_Check(DEVICE_TYPE_FACE))
    {
        Func_Menu_Register(MENU_DELETE_ALLFACE, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    }
    Func_Menu_Register(MENU_SYS_IDENTIFY_MODE, MENU_SYS_SET, Func_Menu_Identyfymode, NULL);
    Func_Menu_Register(MENU_SYS_FACTORY_RESET, MENU_SYS_SET, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_SYS_VOICE_SET, MENU_SYS_SET, Func_Menu_VoiceSet, NULL);
    Func_Menu_Register(MENU_SYS_ALARM_SET, MENU_SYS_SET, Func_Menu_Alarm_Set, NULL);
#ifdef FUNC_SUPPORT_OLED
    Func_Menu_Register(MENU_SYS_TIME_SET, MENU_SYS_SET, Func_Time_Set, NULL);
#endif
#if defined(OPENDOOR_RECORD) || defined(ALL_KINDS_RECORD)
    Func_Menu_Register(MENU_SYS_VIEW_RECORD, MENU_SYS_SET, Func_View_Record, NULL);
#endif
#ifdef FUNC_SUPPORT_ENG
    Func_Menu_Register(MENU_SYS_LANGUE_SET, MENU_SYS_SET, Func_Menu_LangueSet, NULL);
#endif
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_MOTOR_DIR_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Set_Direction, NULL);
    Func_Menu_Register(MENU_MOTOR_DIRVE_LEVEL, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Motor_Power, NULL);
    Func_Menu_Register(MENU_MOTOR_BACK_TIME, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Time, NULL);
    Func_Menu_Register(MENU_AUTO_COLSE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Auto_Close_Time_Set, NULL);
    Func_Menu_Register(MENU_BACK_DRIVE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Drive_Time_Set, NULL);
#endif
    if (Device_Check(DEVICE_TYPE_FACE))
    {
        Func_Menu_Register(MENU_FACE_SENSITIVITY_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Face_Sensitivity_Set, NULL);
    }
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_JOIN_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
    Func_Menu_Register(MENU_EXIT_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
#endif
    Func_Menu_Register(MENU_SYS_ADMIN_CHANGE, MENU_NONE, Func_Menu_Change_Admin_Password, NULL);

#endif
#else

#ifdef FUNC_SUPPORT_ADMINS
    Func_Menu_Register(MENU_ADD_ADMIN, MENU_FIRST_SELECT, Func_Menu_AddAdmin, NULL);
    Func_Menu_Register(MENU_DELETE_ADMIN, MENU_FIRST_SELECT, Func_Menu_DeleteAdmin, NULL);
    Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, Func_Menu_Addnormal, NULL);
    Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
    Func_Menu_Register(MENU_DELETE_SINGLE, MENU_DELETE_COMMON, Func_Menu_DeleteCommon, NULL);
    Func_Menu_Register(MENU_DELETE_USERS, MENU_DELETE_COMMON, NULL, Voice_Second_Delete_User);
    Func_Menu_Register(MENU_SYS_SET, MENU_FIRST_SELECT, NULL, Voice_Second_SysSet);
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_INSTALL_PARAM_SET, MENU_FIRST_SELECT, NULL, Voice_Second_MotorSet);
#endif
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_NET_CONFIG, MENU_FIRST_SELECT, NULL, Voice_Second_NetSet);
#endif
    Func_Menu_Register(MENU_DELETE_ALLPW, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_DELETE_ALLFP, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_DELETE_ALLCARD, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_SYS_IDENTIFY_MODE, MENU_SYS_SET, Func_Menu_Identyfymode, NULL);
    Func_Menu_Register(MENU_SYS_FACTORY_RESET, MENU_SYS_SET, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_SYS_VOICE_SET, MENU_SYS_SET, Func_Menu_VoiceSet, NULL);
    Func_Menu_Register(MENU_SYS_ALARM_SET, MENU_SYS_SET, Func_Menu_Alarm_Set, NULL);
#ifdef FUNC_SUPPORT_OLED
    Func_Menu_Register(MENU_SYS_TIME_SET, MENU_SYS_SET, Func_Time_Set, NULL);
#endif
#if defined(OPENDOOR_RECORD) || defined(ALL_KINDS_RECORD)
    Func_Menu_Register(MENU_SYS_VIEW_RECORD, MENU_SYS_SET, Func_View_Record, NULL);
#endif
#ifdef FUNC_SUPPORT_ENG
    Func_Menu_Register(MENU_SYS_LANGUE_SET, MENU_SYS_SET, Func_Menu_LangueSet, NULL);
#endif
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_MOTOR_DIR_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Set_Direction, NULL);
    Func_Menu_Register(MENU_MOTOR_DIRVE_LEVEL, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Motor_Power, NULL);
    Func_Menu_Register(MENU_MOTOR_BACK_TIME, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Time, NULL);
    Func_Menu_Register(MENU_AUTO_COLSE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Auto_Close_Time_Set, NULL);
    Func_Menu_Register(MENU_BACK_DRIVE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Drive_Time_Set, NULL);
#endif
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_JOIN_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
    Func_Menu_Register(MENU_EXIT_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
#endif

#else
    Func_Menu_Register(MENU_CHANGE_ADMIN_PASSWORD, MENU_FIRST_SELECT, Func_Menu_Change_Admin_Password, NULL);
    Func_Menu_Register(MENU_SET_ADMIN_FINGER, MENU_FIRST_SELECT, Func_Menu_Set_Admin_Finger, NULL);
    Func_Menu_Register(MENU_ADD_NORMAL, MENU_FIRST_SELECT, Func_Menu_Addnormal, NULL);
    Func_Menu_Register(MENU_DELETE_COMMON, MENU_FIRST_SELECT, Func_Menu_DeleteCommon, NULL);
    Func_Menu_Register(MENU_DELETE_USERS, MENU_FIRST_SELECT, NULL, Voice_Second_Delete_User);
    Func_Menu_Register(MENU_SYS_SET, MENU_FIRST_SELECT, NULL, Voice_Second_SysSet);
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_INSTALL_PARAM_SET, MENU_FIRST_SELECT, NULL, Voice_Second_MotorSet);
#endif
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_NET_CONFIG, MENU_FIRST_SELECT, NULL, Voice_Second_NetSet);
#endif
    Func_Menu_Register(MENU_DELETE_ALLPW, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_DELETE_ALLFP, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_DELETE_ALLCARD, MENU_DELETE_USERS, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_SYS_IDENTIFY_MODE, MENU_SYS_SET, Func_Menu_Identyfymode, NULL);
    Func_Menu_Register(MENU_SYS_FACTORY_RESET, MENU_SYS_SET, Func_Menu_Cancle_Insure_Select, NULL);
    Func_Menu_Register(MENU_SYS_VOICE_SET, MENU_SYS_SET, Func_Menu_VoiceSet, NULL);
    Func_Menu_Register(MENU_SYS_ALARM_SET, MENU_SYS_SET, Func_Menu_Alarm_Set, NULL);
#ifdef FUNC_SUPPORT_OLED
    Func_Menu_Register(MENU_SYS_TIME_SET, MENU_SYS_SET, Func_Time_Set, NULL);
#endif
#if defined(OPENDOOR_RECORD) || defined(ALL_KINDS_RECORD)
    Func_Menu_Register(MENU_SYS_VIEW_RECORD, MENU_SYS_SET, Func_View_Record, NULL);
#endif
#ifdef FUNC_SUPPORT_ENG
    Func_Menu_Register(MENU_SYS_LANGUE_SET, MENU_SYS_SET, Func_Menu_LangueSet, NULL);
#endif
#ifdef FUNC_MAIN_MENU_INSTALLATION
    Func_Menu_Register(MENU_MOTOR_DIR_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Set_Direction, NULL);
    Func_Menu_Register(MENU_MOTOR_DIRVE_LEVEL, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Motor_Power, NULL);
    Func_Menu_Register(MENU_MOTOR_BACK_TIME, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Time, NULL);
    Func_Menu_Register(MENU_AUTO_COLSE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Auto_Close_Time_Set, NULL);
    Func_Menu_Register(MENU_BACK_DRIVE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Drive_Time_Set, NULL);
#endif
#ifdef WIFI_MODULE
    Func_Menu_Register(MENU_JOIN_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
    Func_Menu_Register(MENU_EXIT_NET, MENU_NET_CONFIG, Func_Menu_Net_Config, NULL);
#endif
    Func_Menu_Register(MENU_SYS_ADMIN_CHANGE, MENU_NONE, Func_Menu_Change_Admin_Password, NULL);
#endif
#endif
}

static void Func_Menu_Installation(void)
{
    s_menu_list = 0;
    Func_Menu_Register(MENU_INSTALL_PARAM_SET, MENU_NONE, NULL, Voice_Second_MotorSet);
    Func_Menu_Register(MENU_MOTOR_DIR_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Set_Direction, NULL);
    Func_Menu_Register(MENU_MOTOR_DIRVE_LEVEL, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Motor_Power, NULL);
    Func_Menu_Register(MENU_MOTOR_BACK_TIME, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Time, NULL);
    Func_Menu_Register(MENU_AUTO_COLSE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Auto_Close_Time_Set, NULL);
    Func_Menu_Register(MENU_BACK_DRIVE_TIME_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Motor_Back_Drive_Time_Set, NULL);
#ifdef FUNC_SUPPORT_FACE
    if (Device_Check(DEVICE_TYPE_FACE))
    {
        Func_Menu_Register(MENU_FACE_SENSITIVITY_SET, MENU_INSTALL_PARAM_SET, Func_Menu_Face_Sensitivity_Set, NULL);
    }
#endif
}

/***********************************************************************
**函数名:Func_Get_Menu_serial
**功能:获取对应菜单的序列
**参数:
**返回值:返回退出结果
**备注:
***********************************************************************/
static uint8_t Func_Get_Menu_serial(uint8_t menu)
{
    uint8_t i;
    for (i = 0; i < s_menu_list; i++)
    {
        if (g_menulist[i].menuid == menu)
        {
            return i;
        }
    }
    return MENU_LIST_OUT;
}

/***********************************************************************
**函数名:Func_MenuBack
**功能:退出到上级菜单
**参数:
**返回值:返回退出结果
**备注:
***********************************************************************/
static uint8_t Func_MenuBack(void)
{
    //顶级菜单和出厂设置修改管理密码菜单按*号键直接退出
    if ((g_menulist[s_currentmenu].menuid == MENU_FIRST_SELECT) || (g_menulist[s_currentmenu].menuid == MENU_SYS_ADMIN_CHANGE))
    {
        return MENU_LIST_OUT;
    }
    else
    {
        s_Reflash = TRUE;
        return Func_Get_Menu_serial(g_menulist[s_currentmenu].Parent);
    }
}
/***********************************************************************
**函数名:Func_MenuGetList
**功能:获取子菜单项数
**参数:
**返回值:菜单项数
**备注:
***********************************************************************/
static uint8_t Func_MenuGetList(uint32_t menu)
{
    uint8_t i;
    uint8_t menulist = 0;
    for (i = 0; i < s_menu_list; i++)
    {
        if (g_menulist[i].Parent == menu)
        {
            menulist++;
        }
    }
    return menulist;
}

/***********************************************************************
**函数名:Menu_Disp_List
**功能:显示选择的菜单列表
**参数:menu 菜单类型
    index
**返回值:无
**备注:
***********************************************************************/
static void Menu_Disp_List(uint8_t menu, uint8_t index)
{
#ifdef FUNC_SUPPORT_OLED
    uint8_t i;
    uint8_t menulist = 0;
    Disp_Menu_Init();
    for (i = 0; i < s_menu_list; i++)
    {
        if (g_menulist[i].Parent == menu)
        {
            Disp_Menu_Add(g_menulist[i].menuid);
        }
    }
    Disp_Menu_Show(index);
#endif
}
/***********************************************************************
**函数名:Func_Menu_Reflash
**功能:刷新菜单
**参数:
**返回值:无
**备注:
***********************************************************************/
static void Func_Menu_Reflash(void)
{
    s_Reflash = FALSE;
    Keybuff_Clear();
    s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
}

/***********************************************************************
**函数名:Func_Menu_Reflash
**功能:刷新菜单
**参数:
**返回值:无
**备注:
***********************************************************************/
static void Func_Menu_Wait_OLED_Flash(uint32_t time)
{
    BackLed_Value_Set(KEY_LED_ALL_OFF); //等待画面跳转期间按键不能按
    Func_App_Wait_Set_Time(time);
}
/***********************************************************************
**函数名:Func_Menu_Reset
**功能:复位菜单
**参数:
**返回值:无
**备注:
***********************************************************************/
static void Func_Menu_Reset(void)
{
    s_currentmenu = 0;
    s_Reflash = TRUE;
}

/***********************************************************************
**函数名:Func_Menu_Operate_Sucess
**功能:操作成功
**参数:flg 语音是否抢占
**返回值:无
**备注:
***********************************************************************/
static void Func_Menu_Operate_Sucess(uint8_t flg)
{
#ifdef FUNC_SUPPORT_OLED
    Disp_OperaSuccess();
#endif
    Voice_Spk(SPK_OPERATA_SUCESS, flg);
}
/***********************************************************************
**函数名:Func_Menu_Operate_Fail
**功能:操作失败
**参数:flg 语音是否抢占
**返回值:无
**备注:
***********************************************************************/
static void Func_Menu_Operate_Fail(uint8_t flg)
{
#ifdef FUNC_SUPPORT_OLED
    Disp_OperaFail();
#endif
    Voice_Spk(SPK_OPERATA_FAILD, flg);
}
/***********************************************************************
**函数名:Func_MenuIndex
**功能:选择子菜单对应项
**参数:
**返回值:无
**备注:
***********************************************************************/
static uint8_t Func_MenuIndex(uint8_t value)
{
    uint8_t i;
    uint8_t first;
    uint8_t serial = 0;
    for (i = 0; i < s_menu_list; i++)
    {
        if (g_menulist[i].Parent == g_menulist[s_currentmenu].menuid)
        {
            serial++;
            if (serial == (value - '0'))
            {
                return i;
            }
        }
    }
    FUNC_MENU_LOG("select error %d", value);
    return MENU_LIST_ERROR;
}
/***********************************************************************
**函数名:Func_Menu_Led
**功能:语音导航版本控制菜单对应的按键灯背光值
**参数:
**返回值:无
**备注:
***********************************************************************/
static void Func_Menu_Led(void)
{
    uint8_t i;
    uint16_t ledvalue = 0;
    uint8_t list_cnt;
    list_cnt = Func_MenuGetList(g_menulist[s_currentmenu].menuid);
    for (i = 0; i < list_cnt; i++)
    {
        ledvalue |= 1 << i;
    }
    ledvalue |= KEYENTER_LED | KEYSTAR_LED;
    BackLed_Value_Set(ledvalue);
}
/**
 * @brief  判断密码是否太简单
 * @note   简单密码：连续递增、递减的密码、每位密码都相同、密码长度小于PWD_LEN_MIN
 *
 * @param
 * @return 简单返回TRUE  复杂返回FALSE
 */

static uint8_t Func_Menu_Check_Password_Is_Easy(uint8_t *passbuf, uint8_t len)
{
    uint8_t i, cnt1 = 1, cnt2 = 1, cnt3 = 1;
    if (passbuf != NULL)
    {
        for (i = 1; i < len; i++)
        {
            cnt1 = (passbuf[i - 1] == passbuf[i]) ? cnt1 + 1 : 1;
            cnt2 = (passbuf[i - 1] == passbuf[i] - 1) ? cnt2 + 1 : 1;
            cnt3 = (passbuf[i - 1] == passbuf[i] + 1) ? cnt3 + 1 : 1;
        }
        return (cnt1 == len || cnt2 == len || cnt3 == len) ? TRUE : FALSE;
    }
    return FALSE;
}
/***********************************************************************
**函数名:Func_Menu_AddPassword
**功能:添加密码
**参数:
    m_touch 输入按键信息
    password_buff 第一次输入缓存
    count 第一次输入长度
    stid ID起始范围
    endid ID范围
**返回值:添加状态
**备注:stid = endid表示修改用户
***********************************************************************/
static uint32_t Func_Menu_AddPassword(Touch_t *m_touch, uint8_t *password_buff, uint8_t *count, uint16_t *userid, uint8_t stid, uint8_t endid)
{
    uint8_t uid = 0;
    uint32_t status = 0;
    if (!m_touch || !password_buff || !count)
    {
        return status;
    }
    if (m_touch->type == KEY_TYPE_ONCE)
    {
        FUNC_MENU_LOG("*count %d g_keybuff %s g_keylen %d", *count, g_keybuff, g_keylen);
        if (m_touch->keyvalue == '*')
        {
            if (g_keylen)
            {
                if (*count)
                {
                    Keybuff_Clear();
                    Voice_Spk(SPK_INPUT_AGAIN, FALSE);
#ifdef FUNC_SUPPORT_OLED
                    Disp_Input_Password_Again(g_keylen);
#endif
                }
                else
                {
                    status = MENU_STATUS_PASSWORD_CLEAR;
                }
            }
            else
            {
                if (*count)
                {
                    status = MENU_STATUS_PASSWORD_CLEAR;
                }
                else
                {
                    status = MENU_STATUS_BACK;
                }
            }
        }
        else if (m_touch->keyvalue == '#')
        {
            if (g_keylen)
            {
                if (0 == *count) //第一次输入密码
                {
                    if ((g_keylen >= PWD_LEN_MIN) && (g_keylen <= PWD_LEN_MAX))
                    {
                        if (Func_Mem_Check_Password(g_keybuff, &uid, 0, KEYS_QTY_PWD))
                        {
                            status = MENU_STATUS_USER_EXITST;
                        }
                        else if (Func_Menu_Check_Password_Is_Easy(g_keybuff, g_keylen))
                        {
                            status = MENU_STATUS_PASSWORD_EASY;
                        }
                        else
                        {
                            memcpy(password_buff, g_keybuff, g_keylen);
                            (*count)++;
                            Keybuff_Clear();
                            Voice_Spk(SPK_INPUT_AGAIN, FALSE);
#ifdef FUNC_SUPPORT_OLED
                            Disp_Input_Password_Again(g_keylen);
#endif
                        }
                    }
                    else
                    {
                        status = MENU_STATUS_OPERA_FAILED;
                    }
                }
                else
                {
                    if ((g_keylen >= PWD_LEN_MIN) && (g_keylen <= PWD_LEN_MAX) && (!strcmp((const char *)password_buff, (const char *)g_keybuff)))
                    {
                        if (Func_Mem_Get_Idle_Password_id(&uid, stid, endid) || (stid == endid))
                        {
                            if (stid == endid)
                            {
                                uid = stid;
                            }
                            uint8_t flg;
                            flg = Func_Check_PasswordID_Is_Reg(uid, NULL);
                            if (Func_Mem_Save_password(password_buff, uid, s_user_t.authority, g_keylen))
                            {
                                *userid = uid + UID_PASSWORD_OFFSET;
                                status = MENU_STATUS_OPERA_SUCESS;
                                if (flg)
                                {
                                    Func_Mem_Save_Record(RECORD_OPERATION_CHANGE, RECORD_TYPE_PASSWORD, *userid, Get_Current_unixtime());
                                }
                                else
                                {
                                    Func_Mem_Save_Record(RECORD_OPERATION_ADD, RECORD_TYPE_PASSWORD, *userid, Get_Current_unixtime());
                                }
                            }
                            else
                            {
                                status = MENU_STATUS_OPERA_FAILED;
                            }
                        }
                        else
                        {
                            status = MENU_STATUS_USER_FULL;
                        }
                    }
                    else
                    {
                        status = MENU_STATUS_OPERA_FAILED;
                    }
                }
            }
        }
        else if ((m_touch->keyvalue >= '0') && (m_touch->keyvalue <= '9') && (g_keylen < KEY_BUFF_MAX))
        {
            g_keybuff[g_keylen++] = m_touch->keyvalue;
#ifdef FUNC_SUPPORT_OLED
            Disp_Input_KeyValue(g_keylen, NULL);
#endif
            if (g_keylen > PWD_LEN_MAX)
            {
                status = MENU_STATUS_OPERA_FAILED;
            }
        }
    }
    return status;
}
/***********************************************************************
**函数名:Func_Menu_AddCard
**功能:添加卡
**参数:m_card 卡信息
        stid 编号范围
        endid编号范围
**返回值:菜单
**备注:stid = endid表示修改用户
***********************************************************************/
static uint32_t Func_Menu_AddCard(Card_t *m_card, uint16_t *userid, uint8_t stid, uint8_t endid)
{
    uint8_t uid = 0;
    uint32_t status = 0;
    if (m_card && (m_card->operata == CARD_ADD))
    {
        if (Func_Mem_Check_Card(m_card->uid, &uid, 0, KEYS_QTY_CARD))
        {
            status = MENU_STATUS_USER_EXITST;
        }
        else
        {
            if (Func_Mem_Get_Idle_Card_id(&uid, stid, endid))
            {
                if (Func_Mem_Save_Card(m_card->uid, uid, s_user_t.authority, TRUE))
                {
                    FUNC_MENU_LOG("Add card ID %d", uid);
                    *userid = uid + UID_CARD_OFFSET;
                    status = MENU_STATUS_OPERA_SUCESS;
                    Func_Mem_Save_Record(RECORD_OPERATION_ADD, RECORD_TYPE_CARD, *userid, Get_Current_unixtime());
                }
                else
                {
                    status = MENU_STATUS_OPERA_FAILED;
                }
            }
            else
            {
                status = MENU_STATUS_USER_FULL;
            }
        }
    }
    // TASK_LOG("nfc add %d %d\r\n",status,m_card->operata);
    return status;
}
/***********************************************************************
**函数名:Func_Menu_AddFinger
**功能:添加指纹
**参数:m_finger 指纹信息
        stid 编号范围
        endid编号范围
**返回值:菜单
**备注:stid = endid表示修改用户
***********************************************************************/
static uint32_t Func_Menu_AddFinger(Finger_t *m_finger, uint16_t *userid, uint8_t stid, uint8_t endid)
{
    uint32_t status = 0;
    uint8_t flg;
    if (!m_finger)
    {
        return status;
    }
    if (m_finger->optype == FINGER_ADD)
    {
        if ((m_finger->status == FP_ACKCMD_OK) && (m_finger->uid >= stid) && (m_finger->uid <= endid))
        {
            flg = Func_Mem_Check_Finger(m_finger->uid);
            if (Func_Mem_Save_finger(m_finger->uid, s_user_t.authority, TRUE))
            {
                *userid = m_finger->uid + UID_FINGER_OFFSET;
                status = MENU_STATUS_OPERA_SUCESS;
                if (flg) //修改指纹
                {
                    Func_Mem_Save_Record(RECORD_OPERATION_CHANGE, RECORD_TYPE_FINGER, *userid, Get_Current_unixtime());
                }
                else
                {
                    Func_Mem_Save_Record(RECORD_OPERATION_ADD, RECORD_TYPE_FINGER, *userid, Get_Current_unixtime());
                }
            }
            else
            {
                status = MENU_STATUS_OPERA_FAILED;
            }
        }
        else if (m_finger->status == FP_ACKCMD_REG_EXIST)
        {
            status = MENU_STATUS_USER_EXITST;
        }
        else if (m_finger->status == FP_ACKCMD_REG_FAIL)
        {
            status = MENU_STATUS_OPERA_FAILED;
        }
        else if (((m_finger->status == FP_ACKCMD_TIMEOUT) && (stid == 0) && (endid == 0))) //添加管理指纹的时候超时返回直接退出添加菜单
        {
            status = MENU_STATUS_FINGER_TIMEOUT;
        }
        else if ((m_finger->status >= FP_ACKCMD_GETIMG_SUCESS) && (m_finger->status <= FP_ACKCMD_GETIMG_TIMEMAX))
        {
            Voice_Spk(SPK_INPUT_FINGER_AGAIN, TRUE);
#ifdef FUNC_SUPPORT_OLED
            Disp_FingerAgain();
#endif
            Keybuff_Clear();
        }
    }
    return status;
}

/***********************************************************************
**函数名:Func_Menu_Opera_User_Voice
**功能:播放添加用户时的语音
**参数:type 可添加用户类型
**返回值:TRUE 有可添加用户 FALSE 无可添加用户
**备注:
***********************************************************************/
static uint8_t Func_Menu_Opera_User_Voice(uint8_t type)
{
    switch (type)
    {
    case MENU_OPERA_PASSWORD:
        Voice_Spk(SPK_PLS_INPUT_PASS, FALSE);
        return TRUE;
    case MENU_OPERA_CARD:
        Voice_Spk(SPK_PLS_INPUT_CARD, FALSE);
        return TRUE;
    case MENU_OPERA_FINGER:
        Voice_Spk(SPK_INPUT_FINGER, FALSE);
        return TRUE;
    case MENU_OPERA_PASSWORD | MENU_OPERA_CARD | MENU_OPERA_FINGER:
        Voice_Spk(SPK_PLS_ENTER_PASSWORD_FINGER_CARD, FALSE);
        return TRUE;
    case MENU_OPERA_PASSWORD | MENU_OPERA_CARD:
        Voice_Spk(SPK_PLS_INPUT_CARRD_PASSWORD, FALSE);
        return TRUE;
    case MENU_OPERA_PASSWORD | MENU_OPERA_FINGER:
        Voice_Spk(SPK_PLS_INPUT_FINGER_PASSWORD, FALSE);
        return TRUE;
    case MENU_OPERA_FINGER | MENU_OPERA_CARD:
        Voice_Spk(SPK_PLS_INPUT_FINGER_CARD, FALSE);
        return TRUE;
    default:
        return FALSE;
    }
}
/***********************************************************************
**函数名:Func_Menu_Opera_User_Disp
**功能:显示添加用户提示
**参数:type 可添加用户类型
**返回值:
**备注:
***********************************************************************/
static void Func_Menu_Opera_User_Disp(uint8_t type)
{
    uint8_t flg;
    flg = (s_user_t.opera_type == DELETE_USER) ? FALSE : TRUE;
    switch (type)
    {
    case MENU_OPERA_PASSWORD:
        Disp_Opera_Password(flg);
        break;
    case MENU_OPERA_CARD:
        Disp_Opera_Card(flg);
        break;
    case MENU_OPERA_FINGER:
        Disp_Opera_Finger(flg);
        break;
    case MENU_OPERA_PASSWORD | MENU_OPERA_CARD | MENU_OPERA_FINGER:
        Disp_Opera_ALLUser(flg);
        break;
    case MENU_OPERA_PASSWORD | MENU_OPERA_CARD:
        Disp_Opera_Password_Card(flg);
        break;
    case MENU_OPERA_PASSWORD | MENU_OPERA_FINGER:
        Disp_Opera_Finger_Password(flg);
        break;
    case MENU_OPERA_FINGER | MENU_OPERA_CARD:
        Disp_Opera_Finger_Card(flg);
        break;
    default:
        break;
    }
}
/***********************************************************************
**函数名:Func_Menu_Check_User_Full
**功能:判断用户是否已满并提示
**参数:optype 用户类型
**返回值:
**备注:
***********************************************************************/
static uint8_t Func_Menu_Check_User_Full(uint8_t optype)
{
    uint8_t uid;
    switch (optype)
    {
    case DEVICE_TYPE_TOUCH:
        if (!Func_Mem_Get_Idle_Password_id(&uid, ADMIN_PASSWORD_NUM, KEYS_QTY_PWD))
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_PasswordFull();
#endif
            Voice_Spk(SPK_PW_FULL, FALSE);
            return TRUE;
        }
        break;
    case DEVICE_TYPE_FP:
        if ((!Func_Mem_Get_Idle_Finger_id(&uid, ADMIN_FINGER_NUM, Finger_Max_Enroll_Qty())))
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_FingerFull();
#endif
            Voice_Spk(SPK_FP_FULL, FALSE);
            return TRUE;
        }
        break;
    case DEVICE_TYPE_CARD:
        if (!Func_Mem_Get_Idle_Card_id(&uid, ADMIN_CARD_NUM, KEYS_QTY_CARD))
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_CardFull();
#endif
            Voice_Spk(SPK_CARD_FUL, FALSE);
            return TRUE;
        }
        break;
    default:
        break;
    }
    return FALSE;
}
/***********************************************************************
**函数名:Func_Menu_AddUser
**功能:添加用户
**参数:m_device 设备类型 按键 指纹 卡
    pwaddr 密码范围
    fingeraddr 指纹范围
    cardaddr 卡范围
**返回值:
**备注:
***********************************************************************/
static uint8_t Func_Menu_AddUser(Device_t *m_device)
{
    uint8_t uid;
    uint8_t spktype = 0;
    uint32_t status = 0;
    uint16_t user_id = 0;
    static uint8_t count = 0;
    static uint8_t password_buff[PWD_LEN_MAX + 1];

    if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
    {
        Func_Menu_Reflash();
#ifdef FUNC_SUPPORT_ADMINS
        if ((s_user_t.authority == USER_NORMAL) && (SYSTEM_USER_MODE != Func_Mem_Getsystem_Factorystatus()))
        {
            Voice_Spk(SPK_OPERATA_FAILD, FALSE);
#ifdef FUNC_SUPPORT_OLED
            Disp_No_Administrator();
#endif
            return Func_MenuBack();
        }
#endif
        if (Func_Mem_Get_Idle_Password_id(&uid, s_user_t.pw_start, s_user_t.pw_end))
        {
            spktype |= MENU_OPERA_PASSWORD;
        }
        if (Func_Mem_Get_Idle_Card_id(&uid, s_user_t.card_start, s_user_t.card_end))
        {
            spktype |= MENU_OPERA_CARD;
            Card_Ctrl(CARD_ADD);
        }
        else
        {
            Card_Ctrl(CARD_IDLE);
        }
        if (Device_Check(DEVICE_TYPE_FP) && (Func_Mem_Get_Idle_Finger_id(&uid, s_user_t.fp_start, s_user_t.fp_end)))
        {
            Finger_Ctrl(FINGER_ADD, uid, 0);
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_BLUE_BREATH, FP_LED_BLUE_BREATH, 0);
            FUNC_MENU_LOG("Finger_Ctrl ID %d", uid);
            spktype |= MENU_OPERA_FINGER;
        }
        else
        {
            Finger_Ctrl(FINGER_IDLE, 0, 0);
        }
        memset(password_buff, 0, sizeof(password_buff));
        count = 0;
        if (!Func_Menu_Opera_User_Voice(spktype))
        {
            Voice_Spk(SPK_USER_FULL, FALSE);
#ifdef FUNC_SUPPORT_OLED
            Disp_UserFull();
#endif
            return Func_MenuBack();
        }
#ifdef FUNC_SUPPORT_OLED
        Func_Menu_Opera_User_Disp(spktype);
#endif
        Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
        BackLed_Value_Set(KEY_LED_ALL_ON);
    }
    if (!m_device || s_Reflash)
    {
        return s_currentmenu;
    }
    if (m_device->type == DEVICE_TYPE_TOUCH)
    {
        status = Func_Menu_AddPassword((Touch_t *)(m_device->data), password_buff, &count, &user_id, s_user_t.pw_start, s_user_t.pw_end);
    }
    else if (m_device->type == DEVICE_TYPE_FP)
    {
        status = Func_Menu_AddFinger((Finger_t *)(m_device->data), &user_id, s_user_t.fp_start, s_user_t.fp_end);
        if (status == MENU_STATUS_OPERA_SUCESS)
        {
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_GREEN_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
        }
        else if (status && (MENU_STATUS_FINGER_TIMEOUT != status))
        {
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
        }
    }
    else if (m_device->type == DEVICE_TYPE_CARD)
    {
        status = Func_Menu_AddCard((Card_t *)(m_device->data), &user_id, s_user_t.card_start, s_user_t.card_end);
    }
    if (status)
    {
        FUNC_MENU_LOG("Add status %d %d", status, user_id);

        Finger_Ctrl(FINGER_IDLE, 0, 0);
        if (MENU_STATUS_OPERA_SUCESS == status)
        {
            Voice_Spk(SPK_OPERATA_SUCESS, TRUE);
#ifdef FUNC_SUPPORT_OLED
            if (FALSE == Func_Menu_Check_User_Full(m_device->type)) //已满OLED不再显示操作成功
            {
                Disp_Add_Sucess(TRUE, user_id);
            }
#else
            if (user_id)
            {
                Voice_SpkUID(user_id);
            }
            Func_Menu_Check_User_Full(m_device->type);
#endif
        }
        else if (MENU_STATUS_OPERA_FAILED == status)
        {
            Func_Menu_Operate_Fail(TRUE);
        }
        else if (MENU_STATUS_USER_EXITST == status)
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_UserExist();
#endif
            Voice_Spk(SPK_USER_EXIST, TRUE);
        }
        else if (MENU_STATUS_USER_FULL == status)
        {
            Func_Menu_Check_User_Full(m_device->type);
        }
        else if (MENU_STATUS_PASSWORD_EASY == status)
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_Password_Easy();
#endif
            Voice_Spk(SPK_PWD_TOO_SIMPLE, TRUE);
        }
        else if (MENU_STATUS_BACK == status)
        {
            // Finger_Ctrl(FINGER_SLEEP, 0, 0);
            return Func_MenuBack();
        }
        if (MENU_STATUS_PASSWORD_CLEAR != status)
        {
            Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
        }
        s_Reflash = TRUE;
    }
    return s_currentmenu;
}

/***********************************************************************
**函数名:Func_Menu_Set_Admin_Finger
**功能:设置管理员指纹
**参数:m_device 设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Set_Admin_Finger(Device_t *m_device)
{
    uint32_t status = 0;
    Touch_t *m_touch;
    uint16_t user_id;
    if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
    {
        FUNC_MENU_LOG("Func_Menu_Addadmin");
        Func_Set_User_Mode(ADD_USER, USER_ADMIN);
        Func_Set_User_Range(0, ADMIN_PASSWORD_NUM, 0, ADMIN_FINGER_NUM, 0, ADMIN_CARD_NUM);
        Func_Menu_Reflash();
        Finger_Ctrl(FINGER_ADD, 0, 0);
#ifdef MULTIPLE_LED
        BackLed_Value_Set(KEY_LED_CANCEL);
#else
        BackLed_Value_Set(KEY_LED_ALL_ON);
#endif
#ifdef FUNC_SUPPORT_OLED
        Disp_Input_Finger();
#endif
        Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_BLUE_BREATH, FP_LED_BLUE_BREATH, 0);
        Func_Menu_Opera_User_Voice(MENU_OPERA_FINGER);
        Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
    }
    if (!m_device)
    {
        return s_currentmenu;
    }
    if (m_device->type == DEVICE_TYPE_TOUCH)
    {
        m_touch = (Touch_t *)(m_device->data);
        if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (m_touch->keyvalue == '*')
            {
                return Func_MenuBack();
            }
        }
    }
    else if (m_device->type == DEVICE_TYPE_FP)
    {
        status = Func_Menu_AddFinger((Finger_t *)(m_device->data), &user_id, 0, 0);
        if (status)
        {
            s_Reflash = TRUE;
            Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
            if (MENU_STATUS_OPERA_SUCESS == status)
            {
                Func_Menu_Operate_Sucess(TRUE);
                Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_GREEN_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
                return Func_MenuBack();
            }
            else if (MENU_STATUS_USER_EXITST == status)
            {
#ifdef FUNC_SUPPORT_OLED
                Disp_UserExist();
#endif
                Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
                Voice_Spk(SPK_USER_EXIST, TRUE);
            }
            else
            {
                Func_Menu_Operate_Fail(TRUE);
                Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
                if (MENU_STATUS_FINGER_TIMEOUT == status)
                {
                    return Func_MenuBack();
                }
            }
        }
    }
    return s_currentmenu;
}
/***********************************************************************
**函数名:Func_Menu_Change_Admin_Password
**功能:设置管理员密码
**参数:m_device 设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Change_Admin_Password(Device_t *m_device)
{
    uint32_t status = 0;
    static uint8_t count = 0;
    uint16_t user_id;
    static uint8_t password_buff[PWD_LEN_MAX + 1];
    if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
    {
        FUNC_MENU_LOG("Func_Menu_Addadmin");
        Func_Menu_Reflash();
        Func_Set_User_Mode(ADD_USER, USER_ADMIN);
        Func_Set_User_Range(0, ADMIN_PASSWORD_NUM, 0, ADMIN_FINGER_NUM, 0, ADMIN_CARD_NUM);
        if (SYSTEM_INIT_MODE == Func_Mem_Getsystem_Factorystatus()) //第一次进入菜单要先设置管理密码
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_Input_Admin(FALSE);
#endif
            Voice_Spk_Two(SPK_PLEASE, SPK_SET_ADMIN_PWD, FALSE);
        }
        else
        {
            Voice_Spk_Two(SPK_PLEASE, SPK_CHANGE_ADMIN_PASSWORD, FALSE);
            Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
#ifdef FUNC_SUPPORT_OLED
            Disp_Input_Admin(TRUE);
#endif
        }
        BackLed_Value_Set(KEY_LED_ALL_ON);
        memset(password_buff, 0, sizeof(password_buff));
        count = 0;
    }
    if (!m_device)
    {
        return s_currentmenu;
    }
    if (m_device->type == DEVICE_TYPE_TOUCH)
    {
        status = Func_Menu_AddPassword((Touch_t *)(m_device->data), password_buff, &count, &user_id, 0, 0);
        if (status)
        {
            s_Reflash = TRUE;
            if (MENU_STATUS_OPERA_SUCESS == status)
            {
                Func_Menu_Operate_Sucess(TRUE);
                Func_Menu_Reset();
                g_userid = 0;
            }
            else if (MENU_STATUS_USER_EXITST == status)
            {
#ifdef FUNC_SUPPORT_OLED
                Disp_UserExist();
#endif
                Voice_Spk(SPK_USER_EXIST, TRUE);
            }
            else if (MENU_STATUS_PASSWORD_EASY == status)
            {
#ifdef FUNC_SUPPORT_OLED
                Disp_Password_Easy();
#endif
                Voice_Spk(SPK_PWD_TOO_SIMPLE, TRUE);
            }
            else if (MENU_STATUS_BACK == status)
            {
                return Func_MenuBack();
            }
            else if (MENU_STATUS_PASSWORD_CLEAR == status)
            {
                return s_currentmenu;
            }
            else
            {
                Func_Menu_Operate_Fail(TRUE);
            }
            Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
        }
    }
    return s_currentmenu;
}
/***********************************************************************
**函数名:Func_Menu_Addnormal
**功能:添加普通用户
**参数:m_device 设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_AddAdmin(Device_t *m_device)
{
    Func_Set_User_Mode(ADD_USER, USER_ADMIN);
    Func_Set_User_Range(0, ADMIN_PASSWORD_NUM, 0, ADMIN_FINGER_NUM, 0, ADMIN_CARD_NUM);
    return Func_Menu_AddUser(m_device);
}
/***********************************************************************
**函数名:Func_Menu_Addnormal
**功能:添加普通用户
**参数:m_device 设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Addnormal(Device_t *m_device)
{
    Func_Set_User_Mode(ADD_USER, USER_NORMAL);
    Func_Set_User_Range(ADMIN_PASSWORD_NUM, KEYS_QTY_PWD, ADMIN_FINGER_NUM, Finger_Max_Enroll_Qty(), ADMIN_CARD_NUM, KEYS_QTY_CARD);
    return Func_Menu_AddUser(m_device);
}
/***********************************************************************
**函数名:Func_Menu_Delete_UID
**功能:按编号删除用户
**参数:uid 编号

**返回值:删除结果
**备注:
***********************************************************************/
static uint32_t Func_Menu_Delete_UID(uint16_t uid, uint8_t type)
{
    uint32_t status = MENU_STATUS_OPERA_FAILED;
    if ((type & MENU_OPERA_PASSWORD) && (uid >= s_user_t.pw_start + UID_PASSWORD_OFFSET) && (uid < s_user_t.pw_end + UID_PASSWORD_OFFSET))
    {
        if (Func_Check_PasswordID_Is_Reg(uid - UID_PASSWORD_OFFSET, NULL))
        {
            if (Func_Mem_Delete_password(uid - UID_PASSWORD_OFFSET))
            {
                status = MENU_STATUS_OPERA_SUCESS;
                Func_Mem_Save_Record(RECORD_OPERATION_DELETE, RECORD_TYPE_PASSWORD, uid, Get_Current_unixtime());
            }
        }
    }
    else if (Device_Check(DEVICE_TYPE_FP) && (type & MENU_OPERA_FINGER) && (uid >= s_user_t.fp_start + UID_FINGER_OFFSET) && (uid < s_user_t.fp_end + UID_FINGER_OFFSET))
    {
        if (Func_Mem_Check_Finger(uid - UID_FINGER_OFFSET))
        {
            Finger_Ctrl(FINGER_DELETE, uid - UID_FINGER_OFFSET, 1);
            status = 0;
        }
    }
    else if ((type & MENU_OPERA_CARD) && (uid >= s_user_t.card_start + UID_CARD_OFFSET) && (uid < s_user_t.card_end + UID_CARD_OFFSET))
    {
        if (Func_Mem_Check_CardID_Is_Reg(uid - UID_CARD_OFFSET))
        {
            if (Func_Mem_Delete_card(uid - UID_CARD_OFFSET))
            {
                status = MENU_STATUS_OPERA_SUCESS;
                Func_Mem_Save_Record(RECORD_OPERATION_DELETE, RECORD_TYPE_CARD, uid, Get_Current_unixtime());
            }
        }
    }
#ifdef FUNC_SUPPORT_FACE
    else if ((type & MENU_OPERA_FACE) && (uid >= s_user_t.face_start + UID_FACE_OFFSET) && (uid < s_user_t.face_end + UID_FACE_OFFSET))
    {
        if (Func_Mem_Check_Face(uid - UID_FACE_OFFSET, s_user_t.authority))
        {
            Face_Ctrl(FACE_DELETE, TYPE_DELETE_UID, uid - UID_FACE_OFFSET);
            FUNC_MENU_LOG("delete face uid %d", uid - UID_FACE_OFFSET);
            status = 0;
        }
    }
#endif
    return status;
}
/***********************************************************************
**函数名:Func_Menu_Delete_Depend_Numbers
**功能:根据输入的数字进行用户删除或者编号删除
**参数:m_device 设备类型 按键 指纹 卡

**返回值:删除结果
**备注:
***********************************************************************/
static uint32_t Func_Menu_Delete_Depend_Numbers(Touch_t *m_touch, uint8_t type)
{
    uint32_t status = 0;
    uint16_t uid = 0;
    if (!m_touch)
    {
        return status;
    }
    if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
    {
        if (m_touch->keyvalue == '*')
        {
            if (g_keylen)
            {
                status = MENU_STATUS_PASSWORD_CLEAR;
            }
            else
            {
                status = MENU_STATUS_BACK;
            }
        }
        else if (m_touch->keyvalue == '#')
        {
            if (g_keylen)
            {
                if ((type & MENU_OPERA_PASSWORD) && (g_keylen >= PWD_LEN_MIN) && (g_keylen <= PWD_LEN_MAX) && (Func_Mem_Check_Password(g_keybuff, (uint8_t *)&uid, s_user_t.pw_start, s_user_t.pw_end)))
                {
                    if (Func_Mem_Delete_password(uid))
                    {
                        status = MENU_STATUS_OPERA_SUCESS;
                        Func_Mem_Save_Record(RECORD_OPERATION_DELETE, RECORD_TYPE_PASSWORD, uid + UID_PASSWORD_OFFSET, Get_Current_unixtime());
                    }
                    else
                    {
                        status = MENU_STATUS_OPERA_FAILED;
                    }
                }
                else if (UID_LEN == g_keylen) //按编号删除
                {
                    uid = (g_keybuff[0] - '0') * 100 + (g_keybuff[1] - '0') * 10 + (g_keybuff[2] - '0');
                    status = Func_Menu_Delete_UID(uid, type);
                }
                else
                {
                    status = MENU_STATUS_OPERA_FAILED;
                }
            }
        }
        else if ((m_touch->keyvalue >= '0') && (m_touch->keyvalue <= '9') && (g_keylen < KEY_BUFF_MAX))
        {
            g_keybuff[g_keylen++] = m_touch->keyvalue;
#ifdef FUNC_SUPPORT_OLED
            Disp_Input_KeyValue(g_keylen, g_keybuff);
#endif
            if (g_keylen > PWD_LEN_MAX)
            {
                status = MENU_STATUS_OPERA_FAILED;
            }
        }
    }
    return status;
}
/***********************************************************************
**函数名:Func_Menu_DeleteCard
**功能:删除卡，刷卡删除
**参数:m_device 设备类型 按键 指纹 卡

**返回值:删除结果
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteCard(Card_t *m_card)
{
    uint32_t status = 0;
    uint8_t uid = 0;
    if (!m_card)
    {
        return status;
    }
    status = MENU_STATUS_OPERA_FAILED;
    if (Func_Mem_Check_Card(m_card->uid, &uid, s_user_t.card_start, s_user_t.card_end))
    {
        if (Func_Mem_Delete_card(uid))
        {
            status = MENU_STATUS_OPERA_SUCESS;
            Func_Mem_Save_Record(RECORD_OPERATION_DELETE, RECORD_TYPE_CARD, uid + UID_CARD_OFFSET, Get_Current_unixtime());
        }
    }

    return status;
}
/***********************************************************************
**函数名:Func_Menu_DeleteFinger
**功能:删除指纹
**参数:m_finger  指纹信息

**返回值:删除结果
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteFinger(Finger_t *m_finger)
{
    uint32_t status = 0;
    if (!m_finger)
    {
        return status;
    }
    if ((m_finger->optype == FINGER_DELETE) && (m_finger->status == FP_ACKCMD_OK) && (m_finger->uid < Finger_Max_Enroll_Qty()))
    {
        if (Func_Mem_Delete_finger(m_finger->uid))
        {
            Func_Mem_Save_Record(RECORD_OPERATION_DELETE, RECORD_TYPE_FINGER, m_finger->uid + UID_FINGER_OFFSET, Get_Current_unixtime());
            status = MENU_STATUS_OPERA_SUCESS;
        }
        else
        {
            status = MENU_STATUS_OPERA_FAILED;
        }
    }
    else if ((m_finger->optype == FINGER_DELETE) && ((m_finger->status == FP_ACKCMD_DELETE_FAIL) || (m_finger->status == FP_ACKCMD_TIMEOUT)))
    {
        status = MENU_STATUS_OPERA_FAILED;
    }
    else if (m_finger->optype == FINGER_VERIFY)
    {
        if ((m_finger->status == FP_ACKCMD_OK) && (m_finger->uid < s_user_t.fp_end) && (m_finger->uid >= s_user_t.fp_start))
        {
            Finger_Ctrl(FINGER_DELETE, m_finger->uid, 1);
        }
        else
        {
            status = MENU_STATUS_OPERA_FAILED;
        }
    }

    return status;
}
/***********************************************************************
**函数名:Func_Check_Password_Id
**功能:检测是否有可删除密码
**参数:start - end 编号范围

**返回值:
**备注:
***********************************************************************/
static uint8_t Func_Check_Password_Id(uint8_t start, uint8_t end)
{
    uint8_t i = 0;
    uint8_t count = 0;
    for (i = start; i < end; i++)
    {
        if (Func_Check_PasswordID_Is_Reg(i, NULL))
        {
            count++;
        }
    }
    return count;
}

/***********************************************************************
**函数名:Func_Check_Finger_Id
**功能:检测是否有可删除指纹
**参数:start - end 编号范围

**返回值:
**备注:
***********************************************************************/
static uint8_t Func_Check_Finger_Id(uint8_t start, uint8_t end)
{
    uint8_t i = 0;
    uint8_t count = 0;
    for (i = start; i < end; i++)
    {
        if (Func_Mem_Check_Finger(i))
        {
            count++;
        }
    }
    return count;
}

/***********************************************************************
**函数名:Func_Check_Card_Id
**功能:检测是否有可删除卡
**参数:start - end 编号范围

**返回值:
**备注:
***********************************************************************/
static uint8_t Func_Check_Card_Id(uint8_t start, uint8_t end)
{
    uint8_t i = 0;
    uint8_t count = 0;
    for (i = start; i < end; i++)
    {
        if (Func_Mem_Check_CardID_Is_Reg(i))
        {
            count++;
        }
    }
    return count;
}
static uint16_t Func_Get_Admin_count(void)
{
#ifdef FUNC_SUPPORT_FACE
    return Func_Check_Password_Id(0, ADMIN_PASSWORD_NUM) + Func_Check_Finger_Id(0, ADMIN_FINGER_NUM) + Func_Check_Card_Id(0, ADMIN_CARD_NUM) + Func_Check_Store_Face(USER_ADMIN);
#else
    return Func_Check_Password_Id(0, ADMIN_PASSWORD_NUM) + Func_Check_Finger_Id(0, ADMIN_FINGER_NUM) + Func_Check_Card_Id(0, ADMIN_CARD_NUM);
#endif
}
/***********************************************************************
**函数名:Func_Menu_Check_Delete_Type
**功能:检测是否有可删除用户
**参数:deletetype  可删除用户类型

**返回值:
**备注:
***********************************************************************/
static void Func_Menu_Check_Delete_Type(uint8_t *deletetype)
{
    uint8_t i = 0;
    if (deletetype)
    {
        if (Func_Check_Password_Id(s_user_t.pw_start, s_user_t.pw_end))
        {
            (*deletetype) |= MENU_OPERA_PASSWORD;
        }
        if (Func_Check_Finger_Id(s_user_t.fp_start, s_user_t.fp_end))
        {
            (*deletetype) |= MENU_OPERA_FINGER;
        }
        if (Func_Check_Card_Id(s_user_t.card_start, s_user_t.card_end))
        {
            (*deletetype) |= MENU_OPERA_CARD;
        }
    }
}

#ifdef FUNC_SUPPORT_FACE

/***********************************************************************
**函数名:Func_Menu_DeleteFace
**功能:删除指纹
**参数:m_finger  指纹信息

**返回值:删除结果
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteFace(face_feeback_t *m_face)
{
    uint32_t status = 0;
    if (!m_face)
    {
        return status;
    }
    FUNC_MENU_LOG("face delete status %d %d", m_face->status, m_face->uid);
    if ((m_face->status == FACE_DELETE_SUCESS) && (m_face->uid < KEYS_QTY_FACE))
    {
        FUNC_MENU_LOG("face delete sucess %d", m_face->uid);
        if (Func_Mem_Delete_face(m_face->uid))
        {
            Func_Mem_Save_Record(RECORD_OPERATION_DELETE, RECORD_TYPE_FACE, m_face->uid + UID_FACE_OFFSET, Get_Current_unixtime());
            status = MENU_STATUS_OPERA_SUCESS;
        }
        else
        {
            status = MENU_STATUS_OPERA_FAILED;
        }
    }
    else if (m_face->status == FACE_VERIFY_SUCESS)
    {
        if ((m_face->uid >= s_user_t.face_start) && (m_face->uid < s_user_t.face_end))
        {
            Face_Ctrl(FACE_DELETE, TYPE_DELETE_UID, m_face->uid);
        }
        else
        {
            status = MENU_STATUS_OPERA_FAILED;
        }
    }
    else if (m_face->status == FACE_OPERATE_FAIL)
    {
        status = MENU_STATUS_OPERA_FAILED;
    }
    else if ((m_face->status == FACE_TIMEOUT) || (FACE_DELETE_TIMEOUT == m_face->status))
    {
        status = MENU_STATUS_FACE_TIMEOUT;
    }

    return status;
}

/***********************************************************************
**函数名:Func_Menu_Face_Interact
**功能:根据输入进行下一次操作提示
**参数:

**返回值:菜单
**备注:
***********************************************************************/
static void Func_Menu_Face_Interact(uint8_t dir)
{
    if (0 == (dir & FACE_DIRECTION_RIGHT))
    {
        Disp_Face_Right();
        Voice_Spk(SPK_FACE_RIGHT, TRUE);
    }
    else if (0 == (dir & FACE_DIRECTION_LEFT))
    {
        Disp_Face_Left();
        Voice_Spk(SPK_FACE_LEFT, TRUE);
    }
    else if (0 == (dir & FACE_DIRECTION_DOWN))
    {
        Disp_Face_Down();
        Voice_Spk(SPK_FACE_DOWN, TRUE);
    }
    else if (0 == (dir & FACE_DIRECTION_UP))
    {
        Disp_Face_Up();
        Voice_Spk(SPK_FACE_UP, TRUE);
    }
}
/***********************************************************************
**函数名:Func_Menu_Face_Status_Error
**功能:注册时人脸状态错误提示
**参数:

**返回值:菜单
**备注:
***********************************************************************/
static void Func_Menu_Face_Status_Error(s_face_state state)
{
    switch (state)
    {
    case FACE_STATE_TOOUP:
        Voice_Spk(SPK_PLS_LOWER, TRUE);
        break;
    case FACE_STATE_TOODOWN:
        Voice_Spk(SPK_PLS_HIGHER, TRUE);
        break;
    case FACE_STATE_TOOLEFT:
        Voice_Spk(SPK_PLS_RIGHT, TRUE);
        break;
    case FACE_STATE_TOORIGHT:
        Voice_Spk(SPK_PLS_LEFT, TRUE);
        break;
    case FACE_STATE_TOOFAR:
        Voice_Spk(SPK_PLS_APPROACH, TRUE);
        break;
    case FACE_STATE_TOOCLOSE:
        Voice_Spk(SPK_PLS_FAR, TRUE);
        break;
    default:
        break;
    }
}

/***********************************************************************
**函数名:Func_Menu_Delete_Face
**功能:删除人脸用户
**参数:m_device 设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Delete_Face(Device_t *m_device)
{
    uint32_t status = 0;
    Touch_t *m_touch;
    face_feeback_t *m_face;
    uint8_t user_id;
    if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
    {
        FUNC_MENU_LOG("Func_Menu_Delete_Face");
        Func_Menu_Reflash();
        Func_Get_Admin_count();
#ifdef FUNC_SUPPORT_ADMINS
        if (((s_user_t.authority == USER_ADMIN) && (Func_Get_Admin_count() <= 1)) || (0 == Func_Check_Store_Face(s_user_t.authority)))
#else
        if (0 == Func_Check_Store_Face(s_user_t.authority)) //无人脸提示无可删除人脸
#endif
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_No_Face();
#endif
            Voice_Spk(SPK_NO_FACE, FALSE);
            return Func_MenuBack();
        }
        BackLed_Value_Set(KEY_LED_ALL_ON);
#ifdef FUNC_SUPPORT_OLED
        Disp_Face_Camera();
#endif
        Face_Ctrl(FACE_VERIFY, TYPE_DELETE_VERIFY, 0);
        Voice_Spk(SPK_FACE_CAMERA, FALSE);
        Voice_Spk(SPK_INPUT_UID, FALSE);
        Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
    }
    if (!m_device)
    {
        return s_currentmenu;
    }
    if (m_device->type == DEVICE_TYPE_TOUCH)
    {
        status = Func_Menu_Delete_Depend_Numbers((Touch_t *)(m_device->data), MENU_OPERA_FACE);
        if (g_keylen == 1) //输入一个按键就认为准备用编号删除，不再进行人脸验证删除
        {
            Face_Ctrl(FACE_IDLE, TYPE_DEFAULT, 0);
        }
    }
    else if (m_device->type == DEVICE_TYPE_FACE)
    {
        m_face = (face_feeback_t *)(m_device->data);
        status = Func_Menu_DeleteFace(m_face);
    }
    if (status)
    {
        FUNC_MENU_LOG("face delete status %d", status);
        s_Reflash = TRUE;
        if (MENU_STATUS_OPERA_SUCESS == status)
        {
            Func_Menu_Operate_Sucess(TRUE);
        }
        else if (MENU_STATUS_BACK == status)
        {
            return Func_MenuBack();
        }
        else if (MENU_STATUS_PASSWORD_CLEAR == status)
        {
            return s_currentmenu;
        }
        else
        {
            Func_Menu_Operate_Fail(TRUE);
        }
        Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
        if (MENU_STATUS_FACE_TIMEOUT == status)
        {
            return Func_MenuBack();
        }
    }
    return s_currentmenu;
}

static uint32_t Func_Menu_Delete_Admin_Face(Device_t *m_device)
{
    Func_Set_User_Mode(DELETE_USER, USER_ADMIN);
    Func_Set_Face_Range(0, ADMIN_FACE_NUM);
    return Func_Menu_Delete_Face(m_device);
}
static uint32_t Func_Menu_Delete_Common_Face(Device_t *m_device)
{
    Func_Set_User_Mode(DELETE_USER, USER_NORMAL);
    Func_Set_Face_Range(ADMIN_FACE_NUM, KEYS_QTY_FACE);
    return Func_Menu_Delete_Face(m_device);
}

/***********************************************************************
**函数名:Func_Menu_Add_Face
**功能:添加人脸用户
**参数:m_device 设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Add_Face(Device_t *m_device)
{
    uint32_t status = 0;
    Touch_t *m_touch;
    face_feeback_t *m_face;
    uint8_t user_id;
    static uint8_t face_dir_old = 0;
    static uint8_t face_dir_new = 0;
    if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
    {
        Func_Menu_Reflash();
#ifdef FUNC_SUPPORT_ADMINS
        if ((s_user_t.authority == USER_NORMAL) && (SYSTEM_USER_MODE != Func_Mem_Getsystem_Factorystatus()))
        {
            Voice_Spk(SPK_OPERATA_FAILD, FALSE);
#ifdef FUNC_SUPPORT_OLED
            Disp_No_Administrator();
#endif
            return Func_MenuBack();
        }
#else
        if (s_user_t.authority == USER_ADMIN)
        {
            user_id = 0;
        }
        else
#endif
        {
            if ((!Func_Mem_Get_Idle_Face_id(&user_id, s_user_t.face_start, s_user_t.face_end)))
            {
                Voice_Spk(SPK_FACE_FULL, FALSE);
#ifdef FUNC_SUPPORT_OLED
                Disp_FaceFull();
#endif
                return Func_MenuBack();
            }
        }

        Face_Ctrl(FACE_ENROLL, TYPE_DEFAULT, user_id);
#ifdef MULTIPLE_LED
        BackLed_Value_Set(KEY_LED_CANCEL);
#else
        BackLed_Value_Set(KEY_LED_ALL_ON);
#endif
#ifdef FUNC_SUPPORT_OLED
        Disp_Face_Camera();
#endif
        Voice_Spk(SPK_FACE_CAMERA, FALSE);
        Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
        s_overtime = Sys_Timeout_Get(MENU_ADD_FACE_WAIT);
        face_dir_old = 0xff;
        face_dir_new = 0;
    }
    else if ((s_Reflash == FALSE) && (Voice_Check_ListFree()) && (face_dir_new != face_dir_old))
    {
        face_dir_old = face_dir_new;
        Face_Enroll_Control(face_dir_new);
        FUNC_MENU_LOG("enroll dir %d", face_dir_new);
    }
    if (!m_device)
    {
        return s_currentmenu;
    }
    if (m_device->type == DEVICE_TYPE_TOUCH)
    {
        m_touch = (Touch_t *)(m_device->data);
        if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (m_touch->keyvalue == '*')
            {
                s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
                return Func_MenuBack();
            }
        }
    }
    else if (m_device->type == DEVICE_TYPE_FACE)
    {
        m_face = (face_feeback_t *)(m_device->data);
        if (m_face)
        {
            s_overtime = Sys_Timeout_Get(MENU_ADD_FACE_WAIT);
            FUNC_MENU_LOG("FACE MENU status %d dir %d uid %d", m_face->status, m_face->param, m_face->uid);
            if ((m_face->status == FACE_ENROLL_SUCESS) && (m_face->param == ENROLL_ALL_DIRECTION))
            {
                if ((m_face->uid >= 0) && (m_face->uid < KEYS_QTY_FACE)) //中间 右 左 下 上
                {
                    FUNC_MENU_LOG("FACE add sucess %d", m_face->uid);
                    if (!Func_Mem_Check_Face(m_face->uid, USER_ALL_TYPE))
                    {
                        Func_Mem_Save_Record(RECORD_OPERATION_ADD, RECORD_TYPE_FACE, m_face->uid + UID_FACE_OFFSET, Get_Current_unixtime());
                    }
                    else
                    {
                        Func_Mem_Save_Record(RECORD_OPERATION_CHANGE, RECORD_TYPE_FACE, m_face->uid + UID_FACE_OFFSET, Get_Current_unixtime());
                    }
                    Func_Mem_Save_face(m_face->uid, s_user_t.authority, TRUE);
                    s_Reflash = TRUE;
                    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
                    Voice_Spk(SPK_OPERATA_SUCESS, TRUE);
#ifdef FUNC_SUPPORT_OLED
                    Disp_Add_Sucess(TRUE, m_face->uid + UID_FACE_OFFSET);
#else
                    Voice_SpkUID(m_face->uid + UID_FACE_OFFSET);
#endif
#ifndef FUNC_SUPPORT_ADMINS
                    if (s_user_t.authority == USER_ADMIN)
                    {
                        return Func_MenuBack();
                    }
#endif
                }
            }
            else if (FACE_ENROLL_EXIST == m_face->status)
            {
#ifdef FUNC_SUPPORT_OLED
                Disp_UserExist();
#endif
                Voice_Spk(SPK_USER_EXIST, TRUE);
                s_Reflash = TRUE;
                Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
            }
            else if (m_face->status == FACE_ENROLL_STATUS)
            {
                FUNC_MENU_LOG("FACE state error %d", m_face->param);
                if (Voice_Check_ListFree())
                {
                    Func_Menu_Face_Status_Error(m_face->param);
                }
            }
            else if ((m_face->status == FACE_ENROLL_TIMEOUT) || (m_face->status == FACE_TIMEOUT) || (FACE_UNKNOW_ERROR == m_face->status))
            {
                FUNC_MENU_LOG("FACE fail %d", m_face->status);
                Func_Menu_Operate_Fail(TRUE);
                s_Reflash = TRUE;
                Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
                s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
                return Func_MenuBack();
            }
            else if ((m_face->status == FACE_ENROLL_SUCESS) && (m_face->param & (1 << face_dir_new)) && (face_dir_new < 4))
            {
                face_dir_new++;
                Func_Menu_Face_Interact(m_face->param);
                FUNC_MENU_LOG("enroll sucess dir %d", m_face->param);
            }
        }
    }
    return s_currentmenu;
}

static uint32_t Func_Menu_Add_Admin_Face(Device_t *m_device)
{
    Func_Set_User_Mode(ADD_USER, USER_ADMIN);
    Func_Set_Face_Range(0, ADMIN_FACE_NUM);
    return Func_Menu_Add_Face(m_device);
}
static uint32_t Func_Menu_Add_Common_Face(Device_t *m_device)
{
    Func_Set_User_Mode(ADD_USER, USER_NORMAL);
    Func_Set_Face_Range(ADMIN_FACE_NUM, KEYS_QTY_FACE);
    return Func_Menu_Add_Face(m_device);
}

#endif
/***********************************************************************
**函数名:Func_Menu_DeleteSingle
**功能:删除单个用户
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteSingle(Device_t *m_device)
{
    uint8_t spktype = 0;
    uint32_t status = 0;
    if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
    {
        FUNC_MENU_LOG("Func_Menu_DeleteSingle");
        Func_Menu_Reflash();
        // Func_Menu_Check();
        Func_Menu_Check_Delete_Type(&spktype);
        if (!Device_Check(DEVICE_TYPE_FP))
        {
            spktype &= ~MENU_OPERA_FINGER;
        }
        if (spktype & MENU_OPERA_FINGER)
        {
            Finger_Ctrl(FINGER_VERIFY, 0, 0);
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_BLUE_BREATH, FP_LED_BLUE_BREATH, 0);
        }
        else
        {
            Finger_Ctrl(FINGER_IDLE, 0, 0);
        }
        if (spktype & MENU_OPERA_CARD)
        {
            Card_Ctrl(CARD_CHECK);
        }
        else
        {
            Card_Ctrl(CARD_IDLE);
        }
#ifdef FUNC_SUPPORT_ADMINS
        if (((s_user_t.authority == USER_ADMIN) && (Func_Get_Admin_count() <= 1)) || (!Func_Menu_Opera_User_Voice(spktype)))
#else
        if (!Func_Menu_Opera_User_Voice(spktype))
#endif
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_NoUser();
#endif
            Voice_Spk(SPK_NO_USER, FALSE);
            return Func_MenuBack();
        }
#ifdef FUNC_SUPPORT_OLED
        Func_Menu_Opera_User_Disp(spktype);
#endif
        Voice_Spk(SPK_INPUT_UID, FALSE);
        Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
        BackLed_Value_Set(KEY_LED_ALL_ON);
    }
    if (!m_device || s_Reflash)
        return s_currentmenu;
    if (m_device->type == DEVICE_TYPE_TOUCH)
    {
        status = Func_Menu_Delete_Depend_Numbers((Touch_t *)(m_device->data), MENU_OPERA_CARD | MENU_OPERA_FINGER | MENU_OPERA_PASSWORD);
    }
    else if (m_device->type == DEVICE_TYPE_FP)
    {
        status = Func_Menu_DeleteFinger((Finger_t *)(m_device->data));
        if (status == MENU_STATUS_OPERA_SUCESS)
        {
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_GREEN_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
        }
        else if (status && (MENU_STATUS_FINGER_TIMEOUT != status))
        {
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
        }
    }
    else if (m_device->type == DEVICE_TYPE_CARD)
    {
        status = Func_Menu_DeleteCard((Card_t *)(m_device->data));
    }
    if (status)
    {
        FUNC_MENU_LOG("delete status %d", status);

        Finger_Ctrl(FINGER_IDLE, 0, 0);

        s_Reflash = TRUE;
        if (MENU_STATUS_OPERA_SUCESS == status)
        {
            Func_Menu_Operate_Sucess(TRUE);
        }
        else if (MENU_STATUS_BACK == status)
        {
            return Func_MenuBack();
        }
        else if (MENU_STATUS_PASSWORD_CLEAR == status)
        {
            return s_currentmenu;
        }
        else
        {
            Func_Menu_Operate_Fail(TRUE);
        }
        Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    }
    return s_currentmenu;
}

/***********************************************************************
**函数名:Func_Menu_DeleteAllfp
**功能:删除全部指纹
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteAdmin(Device_t *m_device)
{
    Func_Set_User_Mode(DELETE_USER, USER_ADMIN);
    Func_Set_User_Range(0, ADMIN_PASSWORD_NUM, 0, ADMIN_FINGER_NUM, 0, ADMIN_CARD_NUM);
    return Func_Menu_DeleteSingle(m_device);
}

/***********************************************************************
**函数名:Func_Menu_DeleteAllfp
**功能:删除全部指纹
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteCommon(Device_t *m_device)
{
    Func_Set_User_Mode(DELETE_USER, USER_NORMAL);
    Func_Set_User_Range(ADMIN_PASSWORD_NUM, KEYS_QTY_PWD, ADMIN_FINGER_NUM, Finger_Max_Enroll_Qty(), ADMIN_CARD_NUM, KEYS_QTY_CARD);
    return Func_Menu_DeleteSingle(m_device);
}

/***********************************************************************
**函数名:Func_Menu_DeleteAllfp
**功能:删除全部指纹
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteAllfp(Device_t *m_device)
{
    Finger_t *m_finger;
    uint8_t operatype = 0;
    if (!m_device || !m_device->data)
    {
        return s_currentmenu;
    }
    m_finger = (Finger_t *)(m_device->data);
    if (m_device->type == DEVICE_TYPE_FP)
    {
        // TASK_LOG("DeleteAllpw\r\n");
        if ((m_finger->optype == FINGER_DELETE) && (m_finger->status == FP_ACKCMD_OK))
        {
            Func_Menu_Check_Delete_Type(&operatype);
            if (Func_Mem_Clear_Data(USER_FINGER, ADMIN_FINGER_NUM, Finger_Max_Enroll_Qty()))
            {
                if ((operatype & MENU_OPERA_FINGER)) //无指纹提示无可删除指纹
                {
                    Func_Mem_Save_Record(RECORD_OPERATION_CLEAR, RECORD_TYPE_FINGER, 0, Get_Current_unixtime());
                    Func_Menu_Operate_Sucess(TRUE);
                    Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_GREEN_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
                }
                else
                {
#ifdef FUNC_SUPPORT_OLED
                    Disp_No_Finger();
#endif
                    Voice_Spk(SPK_NO_FP, FALSE);
                    Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
                }
            }
            else
            {
                Func_Menu_Operate_Fail(TRUE);
                Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
            }
        }
        else
        {
            Func_Menu_Operate_Fail(TRUE);
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_RED_BREATH, FP_LED_OFF, FINGER_LED_STATUS_DELAY);
        }
        Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
        return Func_MenuBack();
    }
    return s_currentmenu;
}

/***********************************************************************
**函数名:Func_Menu_DeleteAllpw
**功能:删除全部密码
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteAllpw(Device_t *m_device)
{
    uint8_t operatype = 0;
    Func_Menu_Check_Delete_Type(&operatype);
    if (Func_Mem_Clear_Data(USER_PASSWORD, ADMIN_PASSWORD_NUM, KEYS_QTY_PWD)) //无密码提示无可删除密码
    {
        if (operatype & MENU_OPERA_PASSWORD)
        {
            Func_Mem_Save_Record(RECORD_OPERATION_CLEAR, RECORD_TYPE_PASSWORD, 0, Get_Current_unixtime());
            Func_Menu_Operate_Sucess(TRUE);
        }
        else
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_No_Password();
#endif
            Voice_Spk(SPK_NO_PW, FALSE);
        }
    }
    else
    {
        Func_Menu_Operate_Fail(TRUE);
    }
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    return Func_MenuBack();
}
/***********************************************************************
**函数名:Func_Menu_DeleteAllcard
**功能:删除全部卡
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteAllcard(Device_t *m_device)
{
    uint8_t operatype = 0;
    Func_Menu_Check_Delete_Type(&operatype);
    if (Func_Mem_Clear_Data(USER_CARD, ADMIN_CARD_NUM, KEYS_QTY_CARD)) //无卡提示无可删除卡
    {
        if (operatype & MENU_OPERA_CARD)
        {
            Func_Mem_Save_Record(RECORD_OPERATION_CLEAR, RECORD_TYPE_CARD, 0, Get_Current_unixtime());
            Func_Menu_Operate_Sucess(TRUE);
        }
        else
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_No_Card();
#endif
            Voice_Spk(SPK_NO_CARD, FALSE);
        }
    }
    else
    {
        Func_Menu_Operate_Fail(TRUE);
    }
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    return Func_MenuBack();
}
#ifdef FUNC_SUPPORT_FACE
/***********************************************************************
**函数名:Func_Menu_DeleteAllFace
**功能:删除全部面部信息
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_DeleteAllFace(Device_t *m_device)
{
    face_feeback_t *m_face;
    uint8_t operatype = 0;
    if (!m_device || !m_device->data)
    {
        return s_currentmenu;
    }
    m_face = (face_feeback_t *)(m_device->data);
    if (m_device->type == DEVICE_TYPE_FACE)
    {
        TASK_LOG("DeleteAllface %d\r\n", m_face->status);
        if (Func_Check_Store_Face(USER_NORMAL))
        {
            if (m_face->status == FACE_CLEAR_SUCESS)
            {
                Func_Mem_Save_Record(RECORD_OPERATION_CLEAR, RECORD_TYPE_FACE, 0, Get_Current_unixtime());
                Func_Menu_Operate_Sucess(TRUE);
            }
            else
            {
                Func_Menu_Operate_Fail(TRUE);
            }
        }
        else
        {
#ifdef FUNC_SUPPORT_OLED
            Disp_No_Face();
#endif
            Voice_Spk(SPK_NO_FACE, FALSE);
        }
        Func_Mem_Clear_Data(USER_FACE, ADMIN_FACE_NUM, KEYS_QTY_FACE);
        Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
        return Func_MenuBack();
    }
    return s_currentmenu;
}
#endif

/***********************************************************************
**函数名:Func_Menu_Cancle_Insure_Select
**功能:选择操作 根据输入的* # 进行返回和确认
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Cancle_Insure_Select(Device_t *m_device)
{
    uint8_t operatype = 0;
    Touch_t *m_touch;
    static uint8_t flg = FALSE;
    if (s_Reflash)
    {
        FUNC_MENU_LOG("Func_Menu_DeleteUsers");
        Func_Menu_Reflash();
        Func_Set_User_Mode(DELETE_USER, USER_NORMAL);
        Func_Set_User_Range(ADMIN_PASSWORD_NUM, KEYS_QTY_PWD, ADMIN_FINGER_NUM, Finger_Max_Enroll_Qty(), ADMIN_CARD_NUM, KEYS_QTY_CARD);
        Voice_Spk_Three(SPK_PLS_INSURE, SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
#ifdef FUNC_SUPPORT_OLED
        Disp_InSure_Cancel();
#endif
#ifdef MULTIPLE_LED
        BackLed_Value_Set(KEY_LED_CANCEL_INSURE);
#endif
        flg = FALSE;
    }
    if (flg == FALSE)
    {
        if (m_device && (m_device->type == DEVICE_TYPE_TOUCH))
        {
            m_touch = (Touch_t *)(m_device->data);
            if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
            {
                if (m_touch->keyvalue == '*')
                {
                    return Func_MenuBack();
                }
                else if (m_touch->keyvalue == '#')
                {
                    if (g_menulist[s_currentmenu].menuid == MENU_DELETE_ALLFP)
                    {
                        Finger_Ctrl(FINGER_DELETE, ADMIN_FINGER_NUM, Finger_Max_Enroll_Qty() - ADMIN_FINGER_NUM);
                    }
#ifdef FUNC_SUPPORT_FACE
                    else if (g_menulist[s_currentmenu].menuid == MENU_DELETE_ALLFACE)
                    {
                        Face_Ctrl(FACE_CLEAR, TYPE_DEFAULT, ADMIN_FACE_NUM);
                    }
#endif
                    else if (g_menulist[s_currentmenu].menuid == MENU_SYS_FACTORY_RESET)
                    {
                        Finger_Ctrl(FINGER_CLEAR, 0, 0);
                        Card_Ctrl(CARD_IDLE);
#ifdef FUNC_SUPPORT_FACE
                        if (Device_Check(DEVICE_TYPE_FACE))
                        {
                            Face_Ctrl(FACE_CLEAR, TYPE_DEFAULT, 0);
                        }
#endif
                        Control_Send_Mesg(CONTROL_RESET_WIFI, 0);
                        BackLed_Value_Set(KEY_LED_ALL_OFF);
                    }
                    flg = TRUE;
                }
            }
        }
    }
    else
    {
        if (g_menulist[s_currentmenu].menuid == MENU_DELETE_ALLFP)
        {
            return Func_Menu_DeleteAllfp(m_device);
        }
        else if (g_menulist[s_currentmenu].menuid == MENU_DELETE_ALLPW)
        {
            return Func_Menu_DeleteAllpw(m_device);
        }
        else if (g_menulist[s_currentmenu].menuid == MENU_DELETE_ALLCARD)
        {
            return Func_Menu_DeleteAllcard(m_device);
        }
#ifdef FUNC_SUPPORT_FACE
        else if (g_menulist[s_currentmenu].menuid == MENU_DELETE_ALLFACE)
        {
            return Func_Menu_DeleteAllFace(m_device);
        }
#endif
        else if (g_menulist[s_currentmenu].menuid == MENU_SYS_FACTORY_RESET)
        {
            return Func_Menu_Factory_Reset(m_device);
        }
    }

    return s_currentmenu;
}

/***********************************************************************
**函数名:Func_Menu_Identyfymode
**功能:设置验证模式 单开 双开
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Identyfymode(Device_t *m_device)
{
    uint8_t flg;
    if (s_Reflash)
    {
        FUNC_MENU_LOG("Func_Menu_Identyfymode");
        Func_Menu_Reflash();
    }
    if (FALSE == Func_Mem_Getsystem_LockMode())
    {
        Func_Mem_Setsystem_LockMode(TRUE);
    }
    else
    {
        Func_Mem_Setsystem_LockMode(FALSE);
    }
    Func_Menu_Operate_Sucess(FALSE);
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    return Func_MenuBack();
}
/***********************************************************************
**函数名:Func_Menu_Factory_Reset
**功能:恢复出厂设置
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Factory_Reset(Device_t *m_device)
{
    static uint8_t flg = 0;
    if (st_device.type == DEVICE_TYPE_FP)
    {
        if (st_device.data && (((Finger_t *)(st_device.data))->optype == FINGER_CLEAR))
        {
            flg |= CLEAR_FINGER_SUCESS;
            Finger_Ctrl(FINGER_IDLE, 0, 0);
        }
    }
    else if (st_device.type == DEVICE_TYPE_CONTROL)
    {
        if (st_device.data && ((((CONTROL_READ_CTRL *)(st_device.data))->status == SLAVER_ACK_TIMEOUT) || (((CONTROL_READ_CTRL *)(st_device.data))->cmd == CONTROL_WIFI_UP_STATUS)))
        {
            flg |= RESET_WIFI_SUCESS;
        }
    }
#ifdef FUNC_SUPPORT_FACE
    else if (st_device.type == DEVICE_TYPE_FACE)
    {
        flg |= CLEAR_FACE_SUCESS;
        Face_Ctrl(FACE_OFF, TYPE_DEFAULT, 0);
    }
    if (!Device_Check(DEVICE_TYPE_FACE))
    {
        flg |= CLEAR_FACE_SUCESS;
    }
#endif
    if (!Device_Check(DEVICE_TYPE_FP))
    {
        flg |= CLEAR_FINGER_SUCESS;
    }
    if (!Func_Mem_Getsystem_Net_Connect())
    {
        flg |= RESET_WIFI_SUCESS;
    }
#ifdef FUNC_SUPPORT_FACE
    if ((flg == (RESET_WIFI_SUCESS | CLEAR_FINGER_SUCESS | CLEAR_FACE_SUCESS)) || Sys_CheckTimeout(s_overtime))
#else
    if ((flg == (RESET_WIFI_SUCESS | CLEAR_FINGER_SUCESS)) || Sys_CheckTimeout(s_overtime))
#endif
    {
        Func_Factory_Mem_Set();
        Sys_Callback_ReCreate(&s_soft_reset_point, FACTORY_VOICE_WAIT_TIME, 0, NULL, Sys_Reset);
        return MENU_SYS_ADMIN_CHANGE;
    }

    return s_currentmenu;
}

/***********************************************************************
**函数名:Func_Menu_VoiceSet
**功能:语音设置
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_VoiceSet(Device_t *m_device)
{
    Func_Menu_Reflash();
    Func_Menu_Operate_Sucess(FALSE);
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    if (Func_Mem_Getsystem_AudioMode())
    {
        Func_Mem_Setsystem_AudioMode(FALSE);
    }
    else
    {
        Func_Mem_Setsystem_AudioMode(TRUE);
    }
    return Func_MenuBack();
}

/***********************************************************************
**函数名:Func_Menu_LangueSet
**功能:语音设置
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_LangueSet(Device_t *m_device)
{
    Func_Menu_Reflash();

    if (LANGUAUE_CHN == Func_Mem_Getsystem_Langue())
    {
        Func_Mem_Setsystem_LangueMode(LANGUAUE_ENG);
    }
    else
    {
        Func_Mem_Setsystem_LangueMode(LANGUAUE_CHN);
    }
    Func_Menu_Operate_Sucess(FALSE);
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    return Func_MenuBack();
}

/***********************************************************************
**函数名:Func_Menu_Alarm_Set
**功能:防撬设置
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Menu_Alarm_Set(Device_t *m_device)
{
    Func_Menu_Reflash();
    Func_Menu_Operate_Sucess(FALSE);
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    if (Func_Mem_Getsystem_AlarmMode())
    {
        Func_Mem_Setsystem_AlarmMode(FALSE);
        DISABLE_ALARM_IRQ;
    }
    else
    {
        Func_Mem_Setsystem_AlarmMode(TRUE);
        ENABLE_ALARM_IRQ;
    }
    return Func_MenuBack();
}

/***********************************************************************
**函数名:Func_View_Record
**功能:查询记录
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_View_Record(Device_t *m_device)
{
    Touch_t *m_touch;
    Record_stu_t record;
    uint8_t time[6];
    static int16_t index;
    static int16_t total;
    static int16_t recordnum; //当前索引位置
    static int8_t flg = FALSE;

    if (s_Reflash)
    {
        Func_Menu_Reflash();
        flg = FALSE;
        recordnum = Func_Mem_Getsystem_Recordnum();
        index = 1;
        if (recordnum & 0x1000)
        {
            recordnum = recordnum & 0xfff;
            total = KEYS_QTY_RECORD;
        }
        else
        {
            total = recordnum;
        }
        if (total)
        {
            // TASK_LOG("index %d", (recordnum+KEYS_QTY_RECORD-index)%KEYS_QTY_RECORD);
            Func_Mem_Get_Record((recordnum + KEYS_QTY_RECORD - index) % KEYS_QTY_RECORD, &record);
            // TASK_LOG("Record %d %d %d %d",record.operate,record.utype,record.id,record.unixtime);
            TimeUnix_ToBCD(record.unixtime, time);
            // TASK_LOG("time %02x %02x %02x %02x %02x", time[0], time[1], time[2], time[3], time[4]);
            Disp_OpRecord(record.operate, record.utype, record.id, time);
        }
        else
        {
            Disp_NoneRecord();
            Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
            return Func_MenuBack();
        }
        BackLed_Value_Set(KEY_LED_VIEW_RECORD);
    }
    if (m_device && (m_device->type == DEVICE_TYPE_TOUCH))
    {
        m_touch = (Touch_t *)(m_device->data);
        if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (m_touch->keyvalue == '*')
            {
                return Func_MenuBack();
            }
            else if (m_touch->keyvalue == '#')
            {
                Voice_Spk(SPK_FAIL, TRUE);
            }
            if ((MENU_PAGE_UP == m_touch->keyvalue) || (MENU_PAGE_DOWN == m_touch->keyvalue))
            {
                if (MENU_PAGE_UP == m_touch->keyvalue)
                {
                    if (index < total)
                    {
                        index++;
                    }
                    else
                    {
                        Voice_Spk(SPK_FAIL, TRUE);
                    }
                }
                else if (MENU_PAGE_DOWN == m_touch->keyvalue)
                {
                    if (index > 1)
                    {
                        index--;
                    }
                    else
                    {
                        Voice_Spk(SPK_FAIL, TRUE);
                    }
                }
                // TASK_LOG("index %d", (recordnum+KEYS_QTY_RECORD-index)%KEYS_QTY_RECORD);
                Func_Mem_Get_Record((recordnum + KEYS_QTY_RECORD - index) % KEYS_QTY_RECORD, &record);
                // TASK_LOG("Record %d %d %d %d",record.operate,record.utype,record.id,record.unixtime);
                TimeUnix_ToBCD(record.unixtime, time);
                Disp_OpRecord(record.operate, record.utype, record.id, time);
            }
        }
    }

    return s_currentmenu;
}
/***********************************************************************
**函数名:Func_Time_Set
**功能:时间设置
**参数:m_device  设备类型 按键 指纹 卡

**返回值:菜单
**备注:
***********************************************************************/
static uint32_t Func_Time_Set(Device_t *m_device)
{
    Touch_t *m_touch;
    uint8_t buff[6];
    if (s_Reflash)
    {
        Func_Menu_Reflash();
        FUNC_MENU_LOG("Func_Time_Set !");
        BackLed_Value_Set(KEY_LED_ALL_ON);
        Voice_Spk(SPK_SET_TIME, FALSE);
        Voice_Spk_Two(SPK_RETURN_BACK, SPK_PRESS_STAR, FALSE);
        Disp_Set_Time(TRUE, g_keylen, g_keybuff);
    }
    if (m_device && (m_device->type == DEVICE_TYPE_TOUCH))
    {
        m_touch = (Touch_t *)(m_device->data);
        if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (m_touch->keyvalue == '*')
            {
                if (g_keylen)
                {
                    g_keylen--;
                    Disp_Set_Time(TRUE, g_keylen, g_keybuff);
                }
                else
                {
                    return Func_MenuBack();
                }
            }
            else if (m_touch->keyvalue == '#')
            {
                if (TIME_KEY_LENGTH == g_keylen)
                {
                    buff[0] = (g_keybuff[0] * 10) + g_keybuff[1];
                    buff[1] = (g_keybuff[2] * 10) + g_keybuff[3];
                    buff[2] = (g_keybuff[4] * 10) + g_keybuff[5];
                    buff[3] = (g_keybuff[6] * 10) + g_keybuff[7];
                    buff[4] = (g_keybuff[8] * 10) + g_keybuff[9];
                    buff[5] = (g_keybuff[10] * 10) + g_keybuff[11];
                    if (Check_Time(buff))
                    {
                        SetTime(buff);
                        Func_Menu_Operate_Sucess(FALSE);
                    }
                    else
                    {
                        Func_Menu_Operate_Fail(FALSE);
                    }
                }
                else
                {
                    Func_Menu_Operate_Fail(FALSE);
                }
                Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
                return Func_MenuBack();
            }
            else if ((m_touch->keyvalue >= '0') && (m_touch->keyvalue <= '9'))
            {
                if (g_keylen >= TIME_KEY_LENGTH)
                {
                    Voice_Spk(SPK_FAIL, TRUE);
                }
                else
                {
                    g_keybuff[g_keylen++] = m_touch->keyvalue - '0';
                }
                Disp_Set_Time(TRUE, g_keylen, g_keybuff);
            }
        }
    }
    return s_currentmenu;
}

static uint32_t Func_Menu_Motor_Check_Feeback(Device_t *m_device, uint16_t cmd)
{
    CONTROL_READ_CTRL *m_slaver;
    uint8_t *param;
    uint8_t flg = SLAVER_ACK_NONE;
    if (m_device && (m_device->data) && (m_device->type == DEVICE_TYPE_CONTROL))
    {
        m_slaver = m_device->data;
        param = m_slaver->data;
        if (param && (SLAVER_MOTOR_CMD == m_slaver->status) && (cmd == m_slaver->cmd))
        {
            if (SLAVER_FEEBACK_SUCESS == param[0])
            {
                Func_Menu_Operate_Sucess(FALSE);
            }
            else
            {
                Func_Menu_Operate_Fail(FALSE);
            }
            flg = SLAVER_MOTOR_CMD;
        }
        else if (SLAVER_ACK_TIMEOUT == m_slaver->status)
        {
            Func_Menu_Operate_Fail(FALSE);
            flg = SLAVER_ACK_TIMEOUT;
        }
    }
    if (flg)
    {
        Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
        return Func_MenuBack();
    }
    return s_currentmenu;
}

static uint32_t Func_Menu_Motor_Set_Direction(Device_t *m_device)
{
    if (s_Reflash)
    {
        FUNC_MENU_LOG("Func_Menu_Alwaysmode");
        Func_Menu_Reflash();
    }

    if (FALSE == Func_Mem_Getsystem_Motor_Direction())
    {
        Func_Mem_Setsystem_Motor_Direction(TRUE);
    }
    else
    {
        Func_Mem_Setsystem_Motor_Direction(FALSE);
    }

    Func_Menu_Operate_Sucess(FALSE);
    Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
    return Func_MenuBack();
}

static void Func_Disp_Set_Param(uint8_t param)
{
    if (MENU_MOTOR_DIRVE_LEVEL == g_menulist[s_currentmenu].menuid)
    {
        Disp_Motor_Driver_Level(param - MOTOR_POWER_MIN);
    }
    else if ((MENU_AUTO_COLSE_TIME_SET == g_menulist[s_currentmenu].menuid) && (param == 0))
    {
        Disp_Set_Param(param, NULL);
    }
    else if (MENU_BACK_DRIVE_TIME_SET == g_menulist[s_currentmenu].menuid)
    {
        Disp_Set_Param(param * 100, "ms");
    }
#ifdef FUNC_SUPPORT_FACE
    else if (MENU_FACE_SENSITIVITY_SET == g_menulist[s_currentmenu].menuid)
    {
        Disp_Set_Face_Sensitivity(param);
    }
#endif
    else
    {
        Disp_Set_Param(param, "S");
    }
}

/**
 * @brief  输入选择菜单
 * @note
 *
 * @param  m_devic
 *
 * @return 返回菜单项
 */
static uint32_t Func_Menu_Install_Param_Set(Device_t *m_device, const INSTALL_PARAM_INFO *motor_info)
{
    Touch_t *m_touch;
    static uint8_t index;
    static uint8_t enter_flg = FALSE;

    if (s_Reflash)
    {
        Func_Menu_Reflash();
        BackLed_Value_Set(KEY_LED_MENU_SELECT);
        Func_Disp_Set_Param(motor_info->mem_get());
        index = (motor_info->mem_get()) / (motor_info->times);
    }
    if (m_device && (m_device->type == DEVICE_TYPE_TOUCH))
    {
        m_touch = (Touch_t *)(m_device->data);
        if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (m_touch->keyvalue == '*')
            {
                return Func_MenuBack();
            }
            else if (m_touch->keyvalue == MENU_PAGE_UP)
            {
                if (index > motor_info->min)
                {
                    index--;
                }
                else
                {
                    index = motor_info->max;
                }
                Func_Disp_Set_Param(index * (motor_info->times));
            }
            else if (m_touch->keyvalue == MENU_PAGE_DOWN)
            {
                if (index < motor_info->max)
                {
                    index++;
                }
                else
                {
                    index = motor_info->min;
                }
                Func_Disp_Set_Param(index * (motor_info->times));
            }
            else if (m_touch->keyvalue == '#')
            {
                motor_info->mem_save(index * (motor_info->times));
                Func_Menu_Operate_Sucess(FALSE);
                Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
                return Func_MenuBack();
            }
        }
    }
    return s_currentmenu;
}

static uint32_t Func_Menu_Motor_Motor_Power(Device_t *m_device)
{
    return Func_Menu_Install_Param_Set(m_device, s_install_param);
}
static uint32_t Func_Menu_Motor_Back_Time(Device_t *m_device)
{
    return Func_Menu_Install_Param_Set(m_device, s_install_param + 1);
}
static uint32_t Func_Menu_Motor_Auto_Close_Time_Set(Device_t *m_device)
{
    return Func_Menu_Install_Param_Set(m_device, s_install_param + 2);
}
static uint32_t Func_Menu_Motor_Back_Drive_Time_Set(Device_t *m_device)
{
    return Func_Menu_Install_Param_Set(m_device, s_install_param + 3);
}
#ifdef FUNC_SUPPORT_FACE
static uint32_t Func_Menu_Face_Sensitivity_Set(Device_t *m_device)
{
    return Func_Menu_Install_Param_Set(m_device, s_install_param + 4);
}
#endif
#ifdef WIFI_MODULE
static uint32_t Func_Menu_Net_Config(Device_t *m_device)
{
    CONTROL_READ_CTRL *m_slaver;
    uint8_t *param;
    Touch_t *m_touch;

    if (s_Reflash)
    {
        Func_Menu_Reflash();
        Disp_Wait();
        FUNC_MENU_LOG("Func_Menu_Net_Config %d", s_overtime);
        if (g_menulist[s_currentmenu].menuid == MENU_JOIN_NET)
        {
            Control_Send_Mesg(CONTROL_JOIN_WIFI, AP_CONFIG_NET);
            s_overtime = Sys_Timeout_Get(MENU_JOIN_NET_WAIT);
        }
        else
        {
            Control_Send_Mesg(CONTROL_RESET_WIFI, 0);
            s_overtime = Sys_Timeout_Get(MENU_JOIN_NET_WAIT);
        }
        BackLed_Value_Set(KEY_LED_CANCEL);
    }
    if (m_device && (m_device->type == DEVICE_TYPE_CONTROL))
    {
        m_slaver = m_device->data;
        param = m_slaver->data;
        FUNC_MENU_LOG("wifi cmd 0x%04x status %d", m_slaver->cmd, param[0]);
        if (param && (SLAVER_MOTOR_CMD == m_slaver->status) && (CONTROL_WIFI_UP_STATUS == m_slaver->cmd))
        {
            if ((g_menulist[s_currentmenu].menuid == MENU_JOIN_NET) && (JOIN_NET_SUCESS == param[0]) && (param[1]))
            {
                if (Check_Time(&param[2]))
                {
                    SetTime(&param[2]);
                }
                Disp_Encrypting();
                BackLed_Value_Set(KEY_LED_ALL_OFF);
            }
            else
            {
                if ((g_menulist[s_currentmenu].menuid == MENU_JOIN_NET) && (GET_SECRET_KEY_SUCESS == param[0]))
                {
                    Func_Menu_Operate_Sucess(FALSE);
                    Func_Mem_Setsystem_Net_Connect(TRUE);
                }
                else if ((g_menulist[s_currentmenu].menuid == MENU_EXIT_NET) && (RESET_NET_SUCESS == param[0]))
                {
                    Func_Mem_Setsystem_Net_Connect(FALSE);
                    Func_Menu_Operate_Sucess(FALSE);
                }
                else
                {
                    Func_Menu_Operate_Fail(FALSE);
                }
                s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
                Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
                return Func_MenuBack();
            }
        }
        else if (SLAVER_ACK_TIMEOUT == m_slaver->status)
        {
            s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
            Func_Menu_Operate_Fail(FALSE);
            Func_Menu_Wait_OLED_Flash(MENU_OLED_WAIT_TIME);
            return Func_MenuBack();
        }
    }
    else if (m_device && (m_device->type == DEVICE_TYPE_TOUCH))
    {
        m_touch = (Touch_t *)(m_device->data);
        if (m_touch && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (m_touch->keyvalue == '*')
            {
                if (g_menulist[s_currentmenu].menuid == MENU_JOIN_NET)
                {
                    Control_Send_Mesg(CONTROL_JOIN_WIFI, EXIT_CONFIG_NET);
                }
                else
                {
                    Control_Send_Mesg(CONTROL_RESET_WIFI, EXIT_RESET_WIFI);
                }
                s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
                return Func_MenuBack();
            }
        }
    }
    return s_currentmenu;
}
#endif
/**
 * @brief  输入选择菜单
 * @note
 *
 * @param  m_device：输入
 *
 * @return 返回菜单项
 */
static uint8_t Func_MenuSelect(Device_t *m_device)
{
    if (!m_device)
    {
        return s_currentmenu;
    }
    Touch_t *m_touch = (Touch_t *)m_device->data;
    if ((m_device->type == DEVICE_TYPE_TOUCH) && (m_touch->type == KEY_TYPE_ONCE))
    {
#ifndef FUNC_SUPPORT_OLED
        if (m_touch->keyvalue == '*')
        {
            return Func_MenuBack();
        }
        else if (m_touch->keyvalue == '#')
        {
            return MENU_LIST_REFLASH;
        }
        else if ((m_touch->keyvalue >= '0') && (m_touch->keyvalue <= '9'))
        {
            return Func_MenuIndex(m_touch->keyvalue);
        }
#else
        if (m_touch->keyvalue == '*')
        {
            return Func_MenuBack();
        }
        else if (m_touch->keyvalue == '#')
        {
            return Func_MenuIndex(s_Cursor + '1');
        }
        else if (m_touch->keyvalue == MENU_PAGE_UP)
        {
            if (s_Cursor)
                s_Cursor--;
            else
                s_Cursor = Func_MenuGetList(g_menulist[s_currentmenu].menuid) - 1;
            Menu_Disp_List(g_menulist[s_currentmenu].menuid, s_Cursor);
        }
        else if (m_touch->keyvalue == MENU_PAGE_DOWN)
        {
            if (s_Cursor < Func_MenuGetList(g_menulist[s_currentmenu].menuid) - 1)
                s_Cursor++;
            else
                s_Cursor = 0;
            Menu_Disp_List(g_menulist[s_currentmenu].menuid, s_Cursor);
        }
#endif
    }
    return MENU_LIST_NONE;
}
static uint8_t Func_Menu_Check_Touch_Key(Device_t *m_device)
{
    if (!m_device)
    {
        return FALSE;
    }
    Touch_t *m_touch = (Touch_t *)m_device->data;
    if ((m_device->type == DEVICE_TYPE_TOUCH))
    {
        m_touch = (Touch_t *)m_device->data;
        if ((m_touch) && (m_touch->type == KEY_TYPE_ONCE))
        {
            if (BackLed_Check(m_touch->keyvalue))
            {
                BackLed_Click(m_touch->keyvalue);
                Voice_Spk(SPK_DI, TRUE);
                return TRUE;
            }
            else
            {
                m_touch->type = 0; //非需要的按键滤除
            }
        }
    }
    return FALSE;
}

static uint8_t Func_Menu_Check_If_UnLock(Device_t *m_device)
{
    if (!m_device)
    {
        return FALSE;
    }
    CONTROL_READ_CTRL *m_control = m_device->data;
    if ((m_device->type == DEVICE_TYPE_CONTROL))
    {
        if ((m_control) && (SLAVER_MOTOR_CMD == m_control->status) && (CONTROL_MOTOR_UP_STATUS == m_control->cmd))
        {
            if (MOTOR_STA_UNLOCKED_BACK == ((uint8_t *)m_control->data)[0])
            {
                Func_Set_Close_Door_Time();
            }
            else if ((MOTOR_STA_LOCK_START == ((uint8_t *)m_control->data)[0]) || (MOTOR_STA_LOCKED == ((uint8_t *)m_control->data)[0]) || (MOTOR_STA_LOCK_TIMEOUT == ((uint8_t *)m_control->data)[0]))
            {
                Func_Clear_Auto_Close_Time();
            }
        }
    }
    return FALSE;
}

/**
 * @brief  滑盖滑下 退出系统
 * @note
 *
 * @param  m_device：输入
 *
 * @return 返回菜单项
 */
static uint8_t Func_Menu_Check_Slip(Device_t *m_device)
{
    if (!m_device)
    {
        return FALSE;
    }
    Button_t *m_button = (Button_t *)m_device->data;
    if ((m_device->type == DEVICE_TYPE_BUTTON) && (m_button->sensor == BUTTON_SLIP))
    {
        if (m_button->type == BUTTON_TYPE_SHORT)
        {
            if (m_button->value == FALSE) //打开滑盖
            {
                Voice_Spk(SPK_DI, TRUE);
            }
            else
            {
                return TRUE;
            }
        }
    }
    return FALSE;
}
static void Func_Menu_Init(void)
{
    Func_Menu_Reset();
    if (MENU_INSTALLATION == g_menutype)
    {
        Func_Menu_Installation();
    }
    else
    {
        Func_Menu_Management();
#ifndef FUNC_SUPPORT_ADMINS
        if (SYSTEM_INIT_MODE == Func_Mem_Getsystem_Factorystatus()) //第一次进入菜单要先修改管理密码
        {
            s_currentmenu = Func_Get_Menu_serial(MENU_SYS_ADMIN_CHANGE);
            Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_OFF, FP_LED_OFF, 0);
        }
        else
        {
            BackLed_Value_Set(KEY_LED_ALL_OFF);
        }
#else
        BackLed_Value_Set(KEY_LED_ALL_OFF);
#endif
    }
    s_Cursor = 0;
}

/**
 * @brief  菜单任务
 * @note
 *
 * @param  reflashflg：临界刷新标志
 *
 * @return 返回任务ID
 */
uint8_t Func_Menu(uint8_t *reflashflg)
{
    uint8_t select;
    uint8_t slipflg = FALSE;
    Touch_t *m_touch;
    if (!reflashflg)
    {
        return MENU_VERIFY;
    }
    if (*reflashflg == TRUE)
    {
        Func_Menu_Init();
        s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
        Func_App_Wait_Set_Time(0);
        *reflashflg = FALSE;
        Finger_Ctrl(FINGER_IDLE, 0, 0);
        Card_Ctrl(CARD_IDLE);
#ifdef FUNC_SUPPORT_FACE
        Face_Ctrl(FACE_IDLE, TYPE_DEFAULT, 0);
#endif
        FUNC_MENU_LOG("Enter Menu !");
    }
    Func_Menu_Check_Touch_Key(&st_device);
#ifdef AUTO_LOCK_FUNC
    Func_Menu_Check_If_UnLock(&st_device);
#endif
    if ((st_device.data) || (FALSE == Voice_Check_ListFree())) //有任何输入或语音，刷新超时
    {
        if (Sys_Timeout_Get(MENU_TIMEOUT_DELAY) > s_overtime)
        {
            s_overtime = Sys_Timeout_Get(MENU_TIMEOUT_DELAY);
        }
    }
    if (s_currentmenu < s_menu_list)
    {
        if (g_menulist[s_currentmenu].pFunc)
        {
            s_currentmenu = g_menulist[s_currentmenu].pFunc(&st_device);
        }
        else
        {
            if ((s_Reflash) && (!Func_App_Check_Busy()) && (Voice_Check_ListFree()))
            {
                Keybuff_Clear();
                TASK_LOG("Check Voice");
                Finger_Ctrl(FINGER_IDLE, 0, 0);
#ifdef FUNC_SUPPORT_FACE
                Face_Ctrl(FACE_IDLE, TYPE_DEFAULT, 0);
#endif
                Finger_Led_Set(FP_CONTROL_COLOR, FP_LED_OFF, FP_LED_OFF, 0);
                Card_Ctrl(CARD_IDLE);
                s_Cursor = 0;
                Menu_Disp_List(g_menulist[s_currentmenu].menuid, s_Cursor);
#ifndef FUNC_SUPPORT_OLED
                if (g_menulist[s_currentmenu].Audio)
                {
                    g_menulist[s_currentmenu].Audio();
                }
#endif
#ifdef MULTIPLE_LED
#ifndef FUNC_SUPPORT_OLED
                Func_Menu_Led();
#else
                BackLed_Value_Set(KEY_LED_MENU_SELECT);
#endif
#else
                BackLed_Value_Set(KEY_LED_ALL_ON);
#endif
                s_Reflash = FALSE;
            }
            else
            {
                select = Func_MenuSelect(&st_device);
                if (select != MENU_LIST_NONE)
                {
                    if (select == MENU_LIST_OUT)
                    {
                        s_overtime = 0;
                    }
                    else
                    {
                        s_Reflash = TRUE;
                        if ((select < s_menu_list) || (select == MENU_LIST_OUT))
                        {
                            FUNC_MENU_LOG("select menu %d", select);
                            s_currentmenu = select;
                            s_Cursor = 0;
                        }
                    }
                }
            }
        }
    }

    if (Sys_CheckTimeout(s_overtime) || (s_currentmenu == MENU_LIST_OUT) || slipflg)
    {
#ifdef WIFI_MODULE
        if (g_menulist[s_currentmenu].menuid == MENU_JOIN_NET)
        {
            Control_Send_Mesg(CONTROL_JOIN_WIFI, EXIT_CONFIG_NET);
        }
        else if (g_menulist[s_currentmenu].menuid == MENU_EXIT_NET)
        {
            Control_Send_Mesg(CONTROL_RESET_WIFI, EXIT_RESET_WIFI);
        }
#endif
        FUNC_MENU_LOG("Leave Menu!");
        Finger_Ctrl(FINGER_VERIFY, 0, 0);
        Card_Ctrl(CARD_CHECK);
        BackLed_Value_Set(KEY_LED_ALL_OFF);
        Disp_Sleep();
#ifdef FUNC_SUPPORT_FACE
        if (Func_Check_Store_Face(USER_ALL_TYPE) || Func_Mem_Getsystem_Factorystatus())
        {
            Face_Ctrl(FACE_VERIFY, Func_Mem_Getsystem_Factorystatus() ? TYPE_DEMO_MODE : TYPE_DEFAULT, 0);
        }
#endif
        Control_Send_Config();
        Keybuff_Clear();
        return MENU_VERIFY;
    }
    return MENU_MASTER;
}
